diff --git a/docker/.gitignore b/docker/.gitignore new file mode 100644 index 0000000..2ec5195 --- /dev/null +++ b/docker/.gitignore @@ -0,0 +1 @@ +config/ \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 0000000..a344967 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,8 @@ +FROM golang:alpine + +RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing/" >> /etc/apk/repositories && \ + apk add --update openvpn iptables bash git python3 shadow neovim linux-headers musl-dev 3proxy ip6tables gcc && \ + rm -rf /tmp/* /var/tmp/* /var/cache/apk/* /var/cache/distfiles/* + +CMD tail -f /dev/null + diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 0000000..7e64cf0 --- /dev/null +++ b/docker/docker-compose.yml @@ -0,0 +1,16 @@ +version: '3.4' + +services: + ovpn_lb_test: + build: . + container_name: ovpn_lb_test + ports: + - 127.0.0.1:8000:8000 + - 127.0.0.1:7000:7000 + - 127.0.0.1:7001:7001 + volumes: + - /dev/net:/dev/net:z + - ./config:/config + cap_add: + - net_admin + diff --git a/go-socks-lb.yml.template b/go-socks-lb.yml.template index 71932cc..41aaea2 100644 --- a/go-socks-lb.yml.template +++ b/go-socks-lb.yml.template @@ -1,5 +1,5 @@ proxy:{% for i in instances %} - - url: "socks5://192.168.122.128:{{1080+i["idx"]}}" + - url: "socks5://{{ip}}:{{1080+i["idx"]}}" weight: {{i["weight"]}} {% end %} load-balance-mode: "{{load_balance_mode}}" diff --git a/iptable_docker.sh b/iptable_docker.sh index 65fc5df..3b78d7f 100755 --- a/iptable_docker.sh +++ b/iptable_docker.sh @@ -1,6 +1,17 @@ #!/bin/sh # example: -# iptable_docker.sh eth0 172.17.0.0 172.17.0.1 +# iptable_docker.sh $if +if="$1" +gw="$(ip -4 r show dev $if | awk '/default/ {print $3}')" +network="$(ip -o addr show dev $if| awk '$3 == "inet" {print $4}')" +#ip="$(ip -4 a show dev $if | awk -F '[ \t/]+' '/inet .*global/ {print $3}')" + +# Drop all IPv6 traffic +ip6tables -F +ip6tables -X +ip6tables -P OUTPUT DROP +ip6tables -P INPUT DROP + # Flush the tables. This may cut the system's internet. iptables -F iptables -X @@ -9,24 +20,24 @@ iptables -t nat -X iptables -t mangle -F iptables -t mangle -X # Let the VPN client communicate with the outside world. -#iptables -A OUTPUT -j ACCEPT -o $1 -iptables -A OUTPUT -j ACCEPT -o $1 -m owner --gid-owner openvpn +iptables -A OUTPUT -j ACCEPT -o $if -m owner --gid-owner openvpn # The loopback device is harmless, and TUN is required for the VPN. iptables -A OUTPUT -j ACCEPT -o lo - iptables -A OUTPUT -j ACCEPT -o tun+ #iptables -A OUTPUT -j ACCEPT -o tun+ iptables -t mangle -A OUTPUT -m owner --gid-owner openvpn -j MARK --set-mark 11 iptables -t nat -A POSTROUTING -m owner --gid-owner openvpn -o $1 -j MASQUERADE -echo ip route + +echo "flushing ip route table" ip route flush all + +echo "setting up ip rules" ip rule flush ip rule add from all lookup main pref 32766 ip rule add from all lookup default pref 32767 - echo "create route table if it does not exist" if [ $(cat /etc/iproute2/rt_tables | grep novpn | wc -l) -eq 0 ]; then echo "11 novpn" >> /etc/iproute2/rt_tables @@ -34,12 +45,13 @@ fi echo "add to novpn table" ip route flush table novpn -ip route add $2/24 dev $1 -ip route add default via $3 dev $1 table novpn +ip route add $network dev $if +ip route add default via $gw dev $if table novpn echo "add to default table" # need to add a default route for the routing code to trigger the fwmark rule at all, else there's a direct "Network is unreachable" with no packet generated. -ip route add default via 192.168.122.254 dev $1 +# will not allow connection for because is blocked by default +ip route add default via $gw dev $if #echo "disable rp_filter" #for i in /proc/sys/net/ipv4/conf/*/rp_filter; do echo 0 > $i; done @@ -51,8 +63,8 @@ ip rule add fwmark 11 table novpn pref 99 iptables -A INPUT -j ACCEPT -m state --state ESTABLISHED # allow LAN -iptables -A OUTPUT -d $2/24 -j ACCEPT -iptables -A INPUT -s $2/24 -j ACCEPT +iptables -A OUTPUT -d $network -j ACCEPT +iptables -A INPUT -s $network -j ACCEPT iptables -I INPUT -p tcp -m tcp --dport 8388 -j ACCEPT iptables -I INPUT -p tcp -m tcp --dport 2222 -j ACCEPT diff --git a/o_manager.py b/o_manager.py index 20c102b..217194a 100644 --- a/o_manager.py +++ b/o_manager.py @@ -4,12 +4,26 @@ import asyncio from tornado.template import Template import signal import json +import socket +import fcntl +import struct + + +def get_ip_address(ifname): + s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + return socket.inet_ntoa(fcntl.ioctl( + s.fileno(), + 0x8915, # SIOCGIFADDR + struct.pack(b'256s', ifname[:15].encode()) + )[20:24]) class OManager: - def __init__(self, base_folder, base_port=8001, loop=None): + def __init__(self, base_folder, interface, base_port=8001, loop=None): self.base_folder = base_folder self.base_port = base_port + self.interface = interface + self.ip = get_ip_address(self.interface) self.instances = [] self.new_idx = 0 self.weights = [] @@ -48,6 +62,7 @@ class OManager: buf = template_f.read() template = Template(buf) items = { + "ip": self.ip, "instances": self.instances, "dynamic_weight_fp": self.dynamic_weight_fp, "load_balance_mode": load_balance_mode @@ -226,6 +241,6 @@ class OManager: if __name__ == "__main__": folder_fp = "/home/mantao/Desktop/t/" cfg_fp = "/home/mantao/Desktop/t/TCP_Files/UK2-TCP.ovpn" - om = OManager(folder_fp) + om = OManager(folder_fp, "eth0") om.new_op(cfg_fp, "op1", { "auth-user-pass": "/home/mantao/Desktop/t/fast.txt"}) diff --git a/script.sh.template b/script.sh.template index 8750403..db9df20 100644 --- a/script.sh.template +++ b/script.sh.template @@ -24,14 +24,14 @@ fi iptable_mangle_check_add OUTPUT -m owner --gid-owner {{route_table_name}} -j MARK --set-mark {{route_table_id}} iptable_nat_check_add POSTROUTING -m owner --gid-owner {{route_table_name}} -o ${dev} -j MASQUERADE + # populate route table ip route flush table {{route_table_name}} ip route add ${route_vpn_gateway} dev ${dev} src ${ifconfig_local} table {{route_table_name}} ip route add default via ${route_vpn_gateway} table {{route_table_name}} -ip route add 192.168.122.0/24 via 192.168.122.1 dev enp1s0 table {{route_table_name}} + # add vpn_gateway to main route table ip route add ${route_vpn_gateway} dev ${dev} src ${ifconfig_local} - ip rule add fwmark {{route_table_id}} table {{route_table_name}} pref {{rule_pref}} #ip rule add from ${ifconfig_local} table {{route_table_name}} pref {{rule_pref}} iptable_check_add OUTPUT -m mark --mark {{route_table_id}} -j ACCEPT diff --git a/test.py b/test.py index 813a294..8525258 100644 --- a/test.py +++ b/test.py @@ -2,15 +2,20 @@ import tornado.ioloop import tornado.web import json import argparse +import os from o_manager import OManager ap = argparse.ArgumentParser() -ap.add_argument("-s", "--session_folder", required=True, +ap.add_argument("-i", "--interface", required=False, help="path to the session folder") +ap.add_argument("-s", "--session_folder", required=True, + help="path to the session folder", default="eth0") args = vars(ap.parse_args()) session_folder = args["session_folder"] -om = OManager(session_folder) +interface = args["interface"] + +om = OManager(session_folder, interface) class MainHandler(tornado.web.RequestHandler): @@ -115,4 +120,5 @@ def make_app(): if __name__ == "__main__": app = make_app() app.listen(8000) + os.popen("iptable_docker.sh {interface}") tornado.ioloop.IOLoop.current().start()