使用 ipset -R OR iptables-restore 添加规则
优先使用 ipset, 其在流量转发时匹配效率相对 iptables 要高
测试 ss-rules 在 ignore.list 包含 4747 条 IP 的执行用时:
# time /usr/bin/ss-rules -c $CONFIG -i $IGNORE
real 0m 1.34s
user 0m 1.03s
sys 0m 0.30s
使用 ipset -R OR iptables-restore 添加规则
优先使用 ipset, 其在流量转发时匹配效率相对 iptables 要高
测试 ss-rules 在 ignore.list 包含 4747 条 IP 的执行用时:
# time /usr/bin/ss-rules -c $CONFIG -i $IGNORE
real 0m 1.34s
user 0m 1.03s
sys 0m 0.30s
| #!/bin/sh /etc/rc.common | |
| START=95 | |
| SERVICE_USE_PID=1 | |
| SERVICE_WRITE_PID=1 | |
| SERVICE_DAEMONIZE=1 | |
| CONFIG=/etc/shadowsocks/config.json | |
| IGNORE=/etc/shadowsocks/ignore.list | |
| start() { | |
| /usr/bin/ss-rules -c $CONFIG -i $IGNORE && \ | |
| service_start /usr/bin/ss-redir -c $CONFIG | |
| } | |
| stop() { | |
| service_stop /usr/bin/ss-redir && \ | |
| /etc/init.d/firewall restart>/dev/null 2>&1 | |
| } |
| #!/bin/sh | |
| # Get argument | |
| while getopts ":c:i:" arg; do | |
| case $arg in | |
| c) CONFIG=$OPTARG | |
| ;; | |
| i) IGNORE=$OPTARG | |
| ;; | |
| esac | |
| done | |
| # Check ignore list file | |
| if [ -n "$IGNORE" ] && [ -f "$IGNORE" ]; then | |
| LOAD=1 | |
| fi | |
| # Check configuration file | |
| if [ -n "$CONFIG" ] && [ -f "$CONFIG" ]; then | |
| eval $(awk -F'[,:]' '{ | |
| for (i=1; i<=NF; i++) { | |
| if ($i ~ /"server"/) { | |
| printf("server=%s;", $(i+1)) | |
| } | |
| if ($i ~ /"local_port"/) { | |
| printf("local_port=%s;", $(i+1)) | |
| } | |
| } | |
| }' $CONFIG | tr -d '" ') | |
| fi | |
| # Check parameters | |
| if [ -z "$server" ] || [ -z "$local_port" ]; then | |
| echo "Invalid configuration file." | |
| exit 128 | |
| fi | |
| # Use iptables | |
| iptab_r() { | |
| HEAD="*nat\n\ | |
| :SHADOWSOCKS - [0:0]\n\ | |
| -A PREROUTING -p tcp -j SHADOWSOCKS\n\ | |
| -A SHADOWSOCKS -d $server/32 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN\n\ | |
| -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN\n" | |
| TAIL="\n\ | |
| -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports $local_port\n\ | |
| COMMIT" | |
| # Read the ignore list | |
| if [ -n "$LOAD" ]; then | |
| BODY=$(awk '$1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/ { | |
| printf("-A SHADOWSOCKS -d %s -j RETURN\n", $1) | |
| }' $IGNORE) | |
| fi | |
| # Apply the rules | |
| /etc/init.d/firewall restart>/dev/null 2>&1 | |
| echo -e "$HEAD$BODY$TAIL" | iptables-restore -n | |
| exit $? | |
| } | |
| # Use ipset | |
| ipset_r() { | |
| HEAD="create shadowsocks hash:net\n\ | |
| add shadowsocks $server\n\ | |
| add shadowsocks 0.0.0.0/8\n\ | |
| add shadowsocks 10.0.0.0/8\n\ | |
| add shadowsocks 127.0.0.0/8\n\ | |
| add shadowsocks 169.254.0.0/16\n\ | |
| add shadowsocks 172.16.0.0/12\n\ | |
| add shadowsocks 192.168.0.0/16\n\ | |
| add shadowsocks 224.0.0.0/4\n\ | |
| add shadowsocks 240.0.0.0/4\n" | |
| # Read the ignore list | |
| if [ -n "$LOAD" ]; then | |
| BODY=$(awk '$1 ~ /^([0-9]{1,3}\.){3}[0-9]{1,3}/ { | |
| printf("add shadowsocks %s\n", $1) | |
| }' $IGNORE) | |
| fi | |
| # Apply the rules | |
| echo -e "$HEAD$BODY" | ipset -R && \ | |
| iptables -t nat -A PREROUTING -p tcp \ | |
| -m set ! --match-set shadowsocks dst \ | |
| -j REDIRECT --to-ports $local_port | |
| return $? | |
| } | |
| # Catch error codes and select rules mode | |
| ipset -X shadowsocks>/dev/null 2>&1 | |
| [ "$?" = 127 ] && iptab_r | |
| ipset_r || iptab_r | |
| exit $? |