ss_redir_iptables
:- Generate
iptables
redir rules toss_redir
- Auto load and unload
ipset
of china IPs usingchnroute.txt
- Test if an IP is in china IP set.
- Generate
ss_ctl
:- Switch shadowsocks profiles with
systemctl --user
- Switch shadowsocks profiles with
chnroute_refresh
:- Download and parse china IPs based on APNIC record
Last active
October 9, 2017 05:22
-
-
Save nykma/d8492b157b00d89fde21d410824ada85 to your computer and use it in GitHub Desktop.
Shadowsocks-libev-redir @ linux w/ iptables
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# /usr/lib/systemd/system/chinadns.service | |
[Unit] | |
Description=ChinaDNS Service | |
After=network.target | |
[Service] | |
Type=simple | |
User=root | |
ExecStart=/usr/bin/chinadns -m -d -c /etc/chnroute.txt -b 0.0.0.0 -v | |
[Install] | |
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ~/.bin/chnroute_refresh | |
curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > /home/nykma/.config/chnroute.txt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ~/.config/systemd/user/shadowsocks-libev-redir@.service | |
[Unit] | |
Description=Shadowsocks-Libev Client Service Redir Mode | |
After=network.target | |
[Service] | |
Type=simple | |
# CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE | |
ExecStart=/usr/bin/ss-redir -c /etc/shadowsocks/%i.json | |
ExecStartPost=/usr/bin/sudo /home/nykma/.bin/ss_redir_iptables up -c %i | |
ExecStopPost=/usr/bin/sudo /home/nykma/.bin/ss_redir_iptables down | |
[Install] | |
WantedBy=multi-user.target |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# ~/.bin/ss_ctl | |
temp = `systemctl --user status | grep 'shadowsocks-libev-redir@'`.split.find { |text| text.end_with?('.service') } | |
current_profile = temp.nil? ? nil : /(?<=shadowsocks-libev-redir@).*(?=\.service)/.match(temp) | |
target_profile = ARGV[1] || current_profile | |
def service_name(profile) | |
"shadowsocks-libev-redir@#{profile}.service" | |
end | |
def print_info(info) | |
print "#{info} ... " | |
yield | |
print "Complete.\n" | |
end | |
case ARGV[0] | |
when nil, 'status' | |
puts "#{service_name(current_profile)}: " + `systemctl --user status #{service_name(current_profile)} | grep 'Active'` | |
when 'start' | |
exit 'Should give different profile or using `restart`' if target_profile == current_profile | |
unless current_profile.nil? | |
print_info("Stopping #{service_name(current_profile)}") do | |
`systemctl --user stop #{service_name(current_profile)}` | |
end | |
end | |
print_info("Starting #{service_name(target_profile)}") do | |
`systemctl --user start #{service_name(target_profile)}` | |
end | |
when 'stop' | |
print_info("Stopping #{service_name(target_profile)}") do | |
`systemctl --user stop #{service_name(target_profile)}` | |
end | |
when 'restart' | |
print_info "Restarting #{service_name(current_profile)} ..." do | |
`systemctl --user restart #{service_name(current_profile)}` | |
end | |
else | |
abort 'Accepted actions: start stop status restart' | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env fish | |
# ~/.config/fish/completions | |
# Copyright (C) 2012-2014 Dmitry Medvinsky <me@dmedvinsky.name>. All Rights Reserved. | |
# This file is licensed under the GPLv2+. Please see COPYING for more information. | |
set PROG 'ss_ctl' | |
set CONFIG_PATH '/etc/shadowsocks' | |
function __fish_ss_ctl_needs_command | |
set -l cmd (commandline -opc) | |
if [ (count $cmd) -eq 1 -a $cmd[1] = $PROG ] | |
return 0 | |
end | |
return 1 | |
end | |
function __fish_ss_ctl_uses_command | |
set cmd (commandline -opc) | |
if [ (count $cmd) -gt 1 ] | |
if [ $argv[1] = $cmd[2] ] | |
return 0 | |
end | |
end | |
return 1 | |
end | |
function __fish_ss_ctl_print_config_files | |
set -l files | |
eval "set files '$CONFIG_PATH'/**.json" | |
for json in $files | |
echo (echo $json | grep -oh '\w*\.json\b' | sed 's/\.json\b//') | |
end | |
end | |
complete -c $PROG -e | |
complete -c $PROG -f -A -n '__fish_ss_ctl_needs_command' -a start -d 'Command: start or switch a profile' | |
complete -c $PROG -f -A -n '__fish_ss_ctl_needs_command' -a restart -d 'Command: restart current profile' | |
complete -c $PROG -f -A -n '__fish_ss_ctl_needs_command' -a status -d 'Command: show current profile\'s systemctl status' | |
complete -c $PROG -f -A -n '__fish_ss_ctl_needs_command' -a stop -d 'Command: stop current profile' | |
complete -c $PROG -f -A -n '__fish_ss_ctl_uses_command start' -x -a "(__fish_ss_ctl_print_config_files)" -d 'profile' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# ~/.bin/ss_redir_iptables | |
# Set and unset iptables for ss-redir | |
VERSION = '0.1.0'.freeze | |
CHNROUTES_FILE = '/home/nykma/.config/chnroute.txt'.freeze | |
CONFIG_PATH = '/etc/shadowsocks'.freeze | |
LOCAL_ADDR = %w( | |
0.0.0.0/8 | |
10.0.0.0/8 | |
127.0.0.0/8 | |
169.254.0.0/16 | |
172.16.0.0/12 | |
192.168.0.0/16 | |
224.0.0.0/4 | |
240.0.0.0/4 | |
).freeze | |
require 'json' | |
require 'slop' | |
REGEX_IPV4 = /^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/ | |
OPTS = Slop.parse do |o| | |
o.string '-h', '--host', 'Hostname' | |
o.string '-c', '--config', 'Specific config name' | |
o.separator 'other options:' | |
o.on '--version', 'print the version' do | |
puts VERSION | |
exit | |
end | |
end | |
def to_ip(target) | |
if target && !REGEX_IPV4.match(target.to_s) | |
require 'resolv' | |
Resolv.getaddress(target) | |
else | |
target | |
end | |
end | |
def current_config | |
current_config_path = if OPTS[:config] | |
"#{CONFIG_PATH}/#{OPTS[:config]}.json" | |
else | |
temp = `systemctl status | grep 'shadowsocks-libev-redir@'`.split.find do |text| | |
text.end_with?('.service') | |
end | |
current_profile = temp && /(?<=shadowsocks-libev-redir@).*(?=\.service)/.match(temp) | |
current_profile && "#{CONFIG_PATH}/#{current_profile}.json" | |
end | |
(current_config_path && JSON.parse(File.read(current_config_path))) || {} | |
end | |
def print_info(info) | |
print "#{info} ... " | |
yield | |
print "Done.\n" | |
end | |
case OPTS.arguments.first | |
when 'up' | |
unless (target = OPTS[:host] || to_ip(current_config['server'])) | |
puts 'No target given. Abort.' | |
abort | |
end | |
puts "Target: #{target}\n" | |
print_info('Initializing') do | |
`iptables -t nat -N SHADOWSOCKS` | |
`ipset -N chnroute hash:net maxelem 10000` | |
end | |
print_info('Adding Shadowsocks server itself to ignore list') do | |
`iptables -t nat -A SHADOWSOCKS -d #{target} -j RETURN` | |
end | |
print_info('Adding local IP addresses') do | |
LOCAL_ADDR.each do |la| | |
`iptables -t nat -A SHADOWSOCKS -d #{la} -j RETURN` | |
end | |
end | |
print_info('Adding CHNROUTE') do | |
File.open(CHNROUTES_FILE, 'r').each_line do |line| | |
`ipset add chnroute #{line.chomp}` | |
end | |
`iptables -t nat -A SHADOWSOCKS -p tcp -m set --match-set chnroute dst -j RETURN` | |
end | |
print_info('Redirecting') do | |
`iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-port 1080` | |
`iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS` | |
end | |
when 'down' | |
print_info('Cleaning iptables') do | |
`iptables -t nat -D OUTPUT -p tcp -j SHADOWSOCKS` | |
`iptables -t nat -F SHADOWSOCKS` | |
`iptables -t nat -X SHADOWSOCKS` | |
`ipset destroy chnroute` | |
end | |
when 'test' | |
`ipset test chnroute #{to_ip(OPTS.arguments[1])}` | |
else | |
puts OPTS | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment