V2Ray GeoIP for Iran

It is important that your proxy client not send packets to a proxy server when those packets are simply going to return to your own country. A firewall correlating packets can easily see that you are running a proxy server. Instead you must route domestic packets directly.

Domestic IP addresses are defined in the file geoip.dat. Unfortunately you cannot use the standard geoip.dat, because it does not include a section for Iran. If you try to use a rule such as geoip:ir, you will get an error. Instead you must generate your own geoip.dat.

This post shows you how.

Sign up for GeoLite2

You will need a free GeoLite2 account.

Open a browser and visit the MaxMind sign-up page:

https://www.maxmind.com/en/geolite2/signup

Provide your email address and the other details requested.

A password reset link is sent to you by email. You can then log in to MaxMind with your email address and password.

Download GeoLite2 databases

Under Database Products and Subscriptions, click the link Download Databases.

The database you want is GeoLite2 Country: CSV Format.

Download the zip file. It has a name that looks like GeoLite2-Country-CSV_YYYYMMDD.zip.

Unzip the zip file.

The files you will need are:

  • GeoLite2-Country-Locations-en.csv
  • GeoLite2-Country-Blocks-IPv4.csv
  • GeoLite2-Country-Blocks-IPv6.csv

Install Git

We assume you are working on a computer that runs Ubuntu Linux.

Install Git on your computer:

1
2
sudo apt update && sudo apt upgrade -y
sudo apt install -y git

Install Go language

Determine latest version of Go. We will use 1.20.5 in our examples.

Download and extract this version of Go:

1
2
3
sudo rm -rf /usr/local/go
wget https://go.dev/dl/go1.20.5.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.20.5.linux-amd64.tar.gz

Add Go to your path:

1
2
echo 'export PATH=$PATH:/usr/local/go/bin' >> $HOME/.profile
source $HOME/.profile

Check your version of Go:

1
go version

Clone project code

1
git clone https://github.com/v2fly/geoip.git

Install project dependencies

Navigate to project root directory:

1
cd geoip

Install dependencies:

1
go mod download

Copy GeoLite2 files into position

Create a directory for the GeoLite2 databases:

1
mkdir geolite2

Copy the files below into your new ./geolite2 directory. This will be a straight cp if you have them on the same computer, or an scp if they are on a different computer.

  • GeoLite2-Country-Locations-en.csv
  • GeoLite2-Country-Blocks-IPv4.csv
  • GeoLite2-Country-Blocks-IPv6.csv

Edit config file

go run ./ will use config.json in the current directory as the default configuration file.

Edit config.json in your ~/geoip directory.

Make it look like this example. See config-example.json if you want more configuration option examples.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{
"input": [
{
"type": "maxmindGeoLite2CountryCSV",
"action": "add",
"args": {
"country": "./geolite2/GeoLite2-Country-Locations-en.csv",
"ipv4": "./geolite2/GeoLite2-Country-Blocks-IPv4.csv",
"ipv6": "./geolite2/GeoLite2-Country-Blocks-IPv6.csv"
}
},
{
"type": "private",
"action": "add"
},
{
"type": "test",
"action": "add"
}
],
"output": [
{
"type": "v2rayGeoIPDat",
"action": "output",
"args": {
"outputName": "geoip.dat"
}
},
{
"type": "v2rayGeoIPDat",
"action": "output",
"args": {
"outputName": "geoip-only-ir-private.dat",
"wantedList": ["ir", "private"]
}
},
{
"type": "v2rayGeoIPDat",
"action": "output",
"args": {
"oneFilePerList": true,
"wantedList": ["ir", "private", "test"]
}
},
{
"type": "text",
"action": "output"
}
]
}

Save your finished config.json file.

The input is the data source and its input format, whereas the output is the destination of the converted data and its output format. What the run will do is to aggregate all the input format data, then convert them to the output format and write them to the GeoIP file(s), using the options in the config.json file.

Generate GeoIP files

The generated files will be located in the output directory by default. Do go run ./ -h for more usage information. For a standard run, using your finished config.json, just do:

1
2
3
cd ~/geoip
go run ./
ls -l output/dat

GeoIP usage example

Client

1
2
3
4
5
6
cd ~
wget https://github.com/v2fly/v2ray-core/releases/download/v5.7.0/v2ray-linux-64.zip
sudo apt install -y unzip
unzip v2ray-linux-64.zip
cp geoip/output/dat/* .
./v2ray uuid

Edit config.json and use this as an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
{
"log": {
"loglevel": "warning"
},
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": [
"geoip:private",
"geoip:ir"
],
"outboundTag": "direct"
}
]
},
"inbounds": [
{
"listen": "127.0.0.1",
"port": "1080",
"protocol": "socks",
"settings": {
"auth": "noauth",
"udp": true,
"ip": "127.0.0.1"
}
},
{
"listen": "127.0.0.1",
"port": "1081",
"protocol": "http"
}
],
"outbounds": [
{
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "YOUR.SERVER.IP.ADDRESS",
"port": 1234,
"users": [
{
"id": "46daa707-ba12-b549-ff17-2d820486cd66"
}
]
}
]
},
"streamSettings": {
"network": "tcp"
},
"tag": "proxy"
},
{
"protocol": "freedom",
"tag": "direct"
}
]
}

Save the file. Run with this config.json:

1
./v2ray run

Server

1
2
3
su -
apt install -y curl
bash <(curl -L https://raw.githubusercontent.com/v2fly/fhs-install-v2ray/master/install-release.sh)

Edit the configuration file /usr/local/etc/v2ray/config.json, using this as an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
{
"log": {
"loglevel": "warning"
},
"routing": {
"domainStrategy": "AsIs",
"rules": [
{
"type": "field",
"ip": [
"geoip:private",
"geoip:ir"
],
"outboundTag": "block"
}
]
},
"inbounds": [
{
"listen": "0.0.0.0",
"port": 1234,
"protocol": "vmess",
"settings": {
"clients": [
{
"id": "46daa707-ba12-b549-ff17-2d820486cd66"
}
]
},
"streamSettings": {
"network": "tcp"
}
}
],
"outbounds": [
{
"protocol": "freedom",
"tag": "direct"
},
{
"protocol": "blackhole",
"tag": "block"
}
]
}

Enable and start:

1
systemctl enable v2ray; systemctl start v2ray