A Syrian proxy for developers: testing and monitoring from inside Syria
This article is for people building software that needs some of its requests to leave from Syria. It covers when that is useful, how to keep the connection details out of your code, examples for httpx, Node.js and Playwright, and how to handle timeouts and retries on a mobile network. The curl commands and the requests library are covered in Syrian proxy for software and scripts, so they are not repeated here.
When a project needs a Syrian address
- Testing what users in Syria see. Your app or site may behave differently by country: default language, currency, content shown or hidden, or a block at the CDN. A request from a Syrian address shows you the result as it reaches your users there.
- Checking that a Syrian service you integrate with answers. Some Syrian services only respond to requests from inside the country. From abroad you cannot tell whether the problem is your code or the route.
- Monitoring availability from inside Syria. A periodic check of your site or API from a Syrian address catches outages that global monitoring tools miss.
- QA of region-specific content. Before a launch, testers go through the pages and offers meant for Syria from a real Syrian address, not one registered to Syria on a server elsewhere. The difference is explained in Syrian mobile IP vs data center IP.
Keep the credentials out of your code
The username and password are under Connect in your account. Do not put them in a file that goes into the repository. Keep them in a .env file and add it to .gitignore:
# .env (listed in .gitignore) SYRIA_PROXY=http://USER:PASS@gw.syriaproxy.com:2080
Many tools read HTTPS_PROXY and ALL_PROXY on their own, including curl, requests and httpx. Setting them in your shell, though, sends every request those tools make through Syria. A dedicated name such as SYRIA_PROXY that your code reads is clearer, because you decide what goes through the proxy.
If the password contains characters such as @, : or /, percent-encode them before putting them in the URL. If the file ever leaks, press New password in your account.
Python with httpx
This is a mobile network, so give requests a longer timeout than you would for a data center server, and retry with a wait that doubles after each failure:
import os
import time
import httpx
PROXY = os.environ["SYRIA_PROXY"]
TIMEOUT = httpx.Timeout(60.0, connect=20.0)
def fetch(client, url, attempts=4):
for i in range(attempts):
try:
r = client.get(url)
if r.status_code < 500 or i == attempts - 1:
return r
except httpx.TransportError:
if i == attempts - 1:
raise
time.sleep(2 ** i) # 1, 2, 4 seconds
with httpx.Client(proxy=PROXY, timeout=TIMEOUT) as client:
print(fetch(client, "https://api.ipify.org").text)
Retry automatically only the requests that are safe to repeat, such as reads and health checks. A request that creates something or sends money may have gone through before the response was lost, so check its status before sending it again.
Node.js
Install both libraries with npm install undici socks-proxy-agent. For fetch, use undici's ProxyAgent and pass it as dispatcher:
import { fetch, ProxyAgent } from "undici";
const dispatcher = new ProxyAgent(process.env.SYRIA_PROXY);
// SYRIA_PROXY=http://USER:PASS@gw.syriaproxy.com:2080
const res = await fetch("https://api.ipify.org", {
dispatcher,
signal: AbortSignal.timeout(60_000),
});
console.log(await res.text());
For libraries built on http.Agent, such as the built-in https module, use SocksProxyAgent. The socks5h scheme makes domain names resolve in Syria:
import https from "node:https";
import { SocksProxyAgent } from "socks-proxy-agent";
const agent = new SocksProxyAgent("socks5h://USER:PASS@gw.syriaproxy.com:2080");
const req = https.get("https://api.ipify.org", { agent, timeout: 60_000 }, (res) => {
res.setEncoding("utf8");
res.on("data", (chunk) => process.stdout.write(chunk));
});
req.on("timeout", () => req.destroy(new Error("timeout")));
req.on("error", console.error);
Playwright
Chromium does not support SOCKS5 with a username and password, so use HTTP on the same port and pass the details as separate fields:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(proxy={
"server": "http://gw.syriaproxy.com:2080",
"username": "USER",
"password": "PASS",
})
page = browser.new_page()
page.set_default_timeout(60_000)
page.route("**/*", lambda route: route.abort()
if route.request.resource_type in ("image", "media", "font")
else route.continue_())
page.goto("https://api.ipify.org")
print(page.inner_text("body"))
browser.close()
The page.route line stops images, video and fonts from loading. Remove it if your test needs the full page.
Sticky session or rotating address
Address type in your account sets how your main username behaves. Choose Static if your test signs in or goes through several steps that must come from the same address, and Rotating if you want the address to change between requests.
If you run several workers at once and want each to keep its own address, open the Proxy generator and, with Static, pick a hold time between 10 and 120 minutes that is longer than the job. Copy the lines it gives you as they are; do not build the usernames yourself. The number of simultaneous connections per account is limited, so reuse connections instead of opening a new one for every request. More on this in Keeping the same Syrian IP.
Usage is metered per GB
Every byte that goes through the proxy, sent or received, comes out of your balance (Pricing). Send only the requests that need a Syrian address through it, and leave package installs, updates and calls to your other services on your normal connection. For monitoring, request a small page or a light health endpoint rather than the full home page. Rough figures are in How much data you need.
Usage limits
- Mail ports 25, 465 and 587 are blocked, so you cannot send email through the service.
- Bulk scraping and getting around rate limits or bot detection are not allowed, along with everything else in the Acceptable use policy.
- Do not resell access, and do not ship your account details inside software you give to other people. Each user of your software needs their own account.
Questions
Should my code use HTTP or HTTPS?
Port 2443 encrypts the path between your machine and our server, password included, so use it when your library supports it. HTTP on 2080 works with more tools, and the content of https sites stays protected by their own encryption.
How do I know a request really left from Syria?
Make the first step of the test a request to a service that shows your address, and record the result in the test log. If your real address appears, the library is ignoring the proxy setting for that request.
Can I run this in CI?
Yes. Put the URL in your CI secrets, not in a config file, and never print it, because build logs are usually visible to anyone with access to the repository.
Create an account and copy your connection details to send your project's first request from Syria.