Created
August 4, 2019 07:39
-
-
Save zhiguangwang/fa41d0225cc71a6a0ae494eb0ea8e68b to your computer and use it in GitHub Desktop.
Configure the Docker daemon to use ss-local as HTTP/HTTPS proxy.
This file contains hidden or 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 | |
set -e | |
function print_usage { | |
echo | |
echo "Usage: docker-sslocal.sh [OPTIONS]" | |
echo | |
echo "This script is to configure the Docker daemon to use ss-local as HTTP/HTTPS proxy." | |
echo | |
echo "Note: You must run this script as root." | |
echo | |
echo "Options:" | |
echo | |
echo -e " --server-host\t\t(Required) IP or hostname of the Shadowsocks server" | |
echo -e " --server-port\t\t(Required) Port number of the Shadowsocks server" | |
echo -e " --server-password\t(Required) Password of the Shadowsocks server" | |
echo | |
echo -e " --server-name\t\t(Optional) The custom name for the Shadowsocks server. Default value: local" | |
echo -e " --server-cipher\t(Optional) The cipher method used by the Shadowsocks server. Default value: xchacha20-ietf-poly1305" | |
echo -e " --local-port\t\t(Optional) The local port number used by ss-local. Default value: 1080" | |
echo | |
echo | |
echo "Example:" | |
echo | |
echo " docker-sslocal.sh --server-name tokyo --server-host 1.1.1.1 --server-port 8443 --server-password foobar" | |
echo | |
} | |
function log { | |
local readonly level="$1" | |
local readonly message="$2" | |
local readonly timestamp=$(date +"%Y-%m-%d %H:%M:%S") | |
>&2 echo -e "${timestamp} [${level}] ${message}" | |
} | |
function log_info { | |
local readonly message="$1" | |
log "INFO" "$message" | |
} | |
function log_error { | |
local readonly message="$1" | |
log "ERROR" "$message" | |
} | |
function assert_running_as_root { | |
if [[ "$EUID" -ne 0 ]]; then | |
log_error "Please run as root." | |
exit 1 | |
fi | |
} | |
function assert_not_empty { | |
local readonly arg_name="$1" | |
local readonly arg_value="$2" | |
if [[ -z "$arg_value" ]]; then | |
log_error "The value for '$arg_name' cannot be empty" | |
exit 1 | |
fi | |
} | |
function assert_is_installed { | |
local readonly name="$1" | |
if [[ ! $(command -v ${name}) ]]; then | |
log_error "The binary '$name' is required by this script but is not installed or in the system's PATH." | |
exit 1 | |
fi | |
} | |
function install_shadowsocks_libev { | |
apt-get install -y shadowsocks-libev | |
systemctl stop shadowsocks-libev.service | |
systemctl disable shadowsocks-libev.service | |
} | |
function generate_sslocal_systemd_dropin { | |
local readonly systemd_dropin_dir='/etc/systemd/system/[email protected]' | |
mkdir -p "$systemd_dropin_dir" | |
cat > "$systemd_dropin_dir/override.conf" <<EOF | |
[Service] | |
User=nobody | |
Group=nogroup | |
LimitNOFILE=32768 | |
EOF | |
} | |
function generate_sslocal_config { | |
local readonly server_name="$1" | |
local readonly server_host="$2" | |
local readonly server_port="$3" | |
local readonly server_password="$4" | |
local readonly server_cipher="$5" | |
local readonly local_port="$6" | |
local readonly sslocal_config_path="/etc/shadowsocks-libev/$server_name.json" | |
cat > "$sslocal_config_path" <<EOF | |
{ | |
"server": "$server_host", | |
"server_port": $server_port, | |
"local_port": $local_port, | |
"password": "$server_password", | |
"timeout": 60, | |
"method": "$server_cipher", | |
"mode": "tcp_only", | |
"fast_open": true | |
} | |
EOF | |
} | |
function start_sslocal { | |
local readonly server_name="$1" | |
systemctl daemon-reload | |
systemctl enable "shadowsocks-libev-local@$server_name.service" | |
systemctl start shadowsocks-libev-local@$server_name.service | |
} | |
# https://docs.docker.com/config/daemon/systemd/#httphttps-proxy | |
function configure_docker_daemon { | |
local readonly local_port="$1" | |
local readonly systemd_dropin_dir='/etc/systemd/system/docker.service.d' | |
mkdir -p "$systemd_dropin_dir" | |
cat > "$systemd_dropin_dir/override.conf" <<EOF | |
[Service] | |
Environment="ALL_PROXY=socks5h://127.0.0.1:$local_port" | |
EOF | |
systemctl daemon-reload | |
systemctl restart docker | |
} | |
function run { | |
local server_name="local" | |
local server_host="" | |
local server_port="" | |
local server_password="" | |
local server_cipher="xchacha20-ietf-poly1305" | |
local local_port="1080" | |
while [[ $# > 0 ]]; do | |
local key="$1" | |
case "$key" in | |
--server-name) | |
assert_not_empty "$key" "$2" | |
server_name="$2" | |
shift | |
;; | |
--server-host) | |
assert_not_empty "$key" "$2" | |
server_host="$2" | |
shift | |
;; | |
--server-port) | |
assert_not_empty "$key" "$2" | |
server_port="$2" | |
shift | |
;; | |
--server-password) | |
assert_not_empty "$key" "$2" | |
server_password="$2" | |
shift | |
;; | |
--server-cipher) | |
assert_not_empty "$key" "$2" | |
server_cipher="$2" | |
shift | |
;; | |
--local-port) | |
assert_not_empty "$key" "$2" | |
local_port="$2" | |
shift | |
;; | |
--help) | |
print_usage | |
exit | |
;; | |
*) | |
log_error "Unrecognized argument: $key" | |
print_usage | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
assert_running_as_root | |
assert_is_installed "docker" | |
assert_not_empty "--server-host" "$server_host" | |
assert_not_empty "--server-port" "$server_port" | |
assert_not_empty "--server-password" "$server_password" | |
install_shadowsocks_libev | |
generate_sslocal_systemd_dropin | |
generate_sslocal_config \ | |
"$server_name" \ | |
"$server_host" \ | |
"$server_port" \ | |
"$server_password" \ | |
"$server_cipher" \ | |
"$local_port" | |
start_sslocal "$server_name" | |
configure_docker_daemon "$local_port" | |
} | |
run "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment