Linux autossh + ssh 设置 sockets5 代理翻墙
Linux – LSBInitScript

系统服务脚本 /etc/init.d/autossh-proxy:

#!/bin/sh

### BEGIN INIT INFO
# Provides:          autossh-proxy
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: start and stop autossh-proxy
# Description:       autossh-proxy is a manager of socket5 proxy by ssh
### END INIT INFO

# Author: lizs <lizsmail.com>

PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

NAME=autossh
AUTOSSH=/usr/bin/autossh
AUTOSSH_PIDFILE=/var/run/$NAME.pid
# AUTOSSH_LOGFILE=/var/log/$BASE.log
# autossh can use environment variables to control features, e.g. AUTOSSH_PID.
# more info see `man autossh`
AUTOSSH_PID="/usr/bin/env AUTOSSH_PIDFILE=${AUTOSSH_PIDFILE}"
# The autossh args
AUTOSSH_ARGS="-M 0 -fqTN -D 1080 root@alizs.cc"

# Get lsb functions
. /lib/lsb/init-functions

do_start()
{
    start-stop-daemon --start --quiet --oknodo \
        --pidfile $AUTOSSH_PIDFILE \
        --make-pidfile \
        --exec $AUTOSSH_PID $AUTOSSH \
        -- $AUTOSSH_ARGS
    RETVAL="$?"
    return "${RETVAL}"
}

do_stop()
{
    # Return
    # 0 if the daemon has been stopped
    # 2 if the daemon could not be stopped
    # other if a failure occured
    start-stop-daemon --stop --quiet --oknodo \
        --retry=TERM/5/KILL/5 \
        --pidfile $AUTOSSH_PIDFILE \
        --remove-pidfile
    RETVAL="$?"
    return "${RETVAL}"
}

do_restart()
{
    exit 0
}


case "$1" in
    status)
        if init_is_upstart; then
            exit 1
        fi
        status_of_proc -p "${AUTOSSH_PIDFILE}" "${AUTOSSH}" "${NAME}"
        ;;
    start)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Starting ${NAME}..."
        do_start
        log_end_msg "$?" # e.g. [ok], failed!, (warning)
        ;;
    stop)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Stopping ${NAME}..."
        do_stop
        log_end_msg "$?"
        ;;
    restart)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Restarting ${NAME}"
        do_restart
        log_end_msg "$?"
        ;;
    force-reload)
        exit 0
        ;;
    *)
        log_failure_msg "Usage: service ${NAME} {status|start|stop|restart}"
        ;;
esac

添加系统服务

将服务脚本添加到 /etc/init.d/ 目录下之后,就可以添加系统服务了。

  • CentOS
    Redhat 提供了 chkconfig 命令来管理系统的服务:

    • chkconfig --list:所有服务列表
    • chkconfig --list serviceName:只显示 serverName 服务
    • chkconfig serviceName on:开启 serverName 服务的自动启动
    • chkconfig serviceName off:关闭 serverName 服务的自动启动
    • chkconfig --add serviceName:添加服务
    • chkconfig --del serviceName:删除服务
  • Ubuntu
    Ubuntu 是没有 chkconfig 命令的,而是提供了另外的命令来实现管理服务:

    • sudo update-rc.d serviceName defaults:添加服务,默认添加服务为自动启动,即 /etc/rc0.d//etc/rc6.d 各级别里面都添加了服务的启动软链接。
    • sudo update-rc.d serviceName remove:删除服务,默认会删除所有级别的服务,即彻底删除服务。

      如果,你想要配置各级别的启动情况,可以删除相应级别目录里面的服务软链接。

    • systemctl daemon-reload:修改过服务之后,用该命令来重新加载服务。

#!/bin/sh

### BEGIN INIT INFO
# Provides:          autossh-proxy
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: start and stop autossh-proxy
# Description:       autossh-proxy is a manager of socket5 proxy by ssh
### END INIT INFO

# Author: lizs <lizsmail.com>

PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

NAME=autossh
AUTOSSH=/usr/bin/autossh
AUTOSSH_PIDFILE=/var/run/$NAME.pid
# AUTOSSH_LOGFILE=/var/log/$BASE.log
# autossh can use environment variables to control features, e.g. AUTOSSH_PID.
# more info see `man autossh`
AUTOSSH_PID="/usr/bin/env AUTOSSH_PIDFILE=${AUTOSSH_PIDFILE}"
# The autossh args
AUTOSSH_ARGS="-M 0 -fqTN -D 1080 root@alizs.cc"

# Get lsb functions
. /lib/lsb/init-functions

do_start()
{
    start-stop-daemon --start --quiet --oknodo \
        --pidfile $AUTOSSH_PIDFILE \
        --make-pidfile \
        --exec $AUTOSSH_PID $AUTOSSH \
        -- $AUTOSSH_ARGS
    RETVAL="$?"
    return "${RETVAL}"
}

do_stop()
{
    # Return
    # 0 if the daemon has been stopped
    # 2 if the daemon could not be stopped
    # other if a failure occured
    start-stop-daemon --stop --quiet --oknodo \
        --retry=TERM/5/KILL/5 \
        --pidfile $AUTOSSH_PIDFILE \
        --remove-pidfile
    RETVAL="$?"
    return "${RETVAL}"
}

do_restart()
{
    exit 0
}


case "$1" in
    status)
        if init_is_upstart; then
            exit 1
        fi
        status_of_proc -p "${AUTOSSH_PIDFILE}" "${AUTOSSH}" "${NAME}"
        ;;
    start)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Starting ${NAME}..."
        do_start
        log_end_msg "$?" # e.g. [ok], failed!, (warning)
        ;;
    stop)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Stopping ${NAME}..."
        do_stop
        log_end_msg "$?"
        ;;
    restart)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Restarting ${NAME}"
        do_restart
        log_end_msg "$?"
        ;;
    force-reload)
        exit 0
        ;;
    *)
        log_failure_msg "Usage: service ${NAME} {status|start|stop|restart}"
        ;;
esac

wiki: LSBInitScripts
Linux Standard Base Core Specification 3.1

#!/bin/sh

### BEGIN INIT INFO
# Provides:          autossh-proxy
# Required-Start:    $network
# Required-Stop:     $network
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: start and stop autossh-proxy
# Description:       autossh-proxy is a manager of socket5 proxy by ssh
### END INIT INFO

# Author: lizs <lizsmail.com>

PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

NAME=autossh
AUTOSSH=/usr/bin/autossh
AUTOSSH_PIDFILE=/var/run/$NAME.pid
# AUTOSSH_LOGFILE=/var/log/$BASE.log
# autossh can use environment variables to control features, e.g. AUTOSSH_PID.
# more info see `man autossh`
AUTOSSH_PID="/usr/bin/env AUTOSSH_PIDFILE=${AUTOSSH_PIDFILE}"
# The autossh args
AUTOSSH_ARGS="-M 0 -fqTN -D 1080 root@alizs.cc"

# Get lsb functions
. /lib/lsb/init-functions

do_start()
{
    start-stop-daemon --start --quiet --oknodo \
        --pidfile $AUTOSSH_PIDFILE \
        --make-pidfile \
        --exec $AUTOSSH_PID $AUTOSSH \
        -- $AUTOSSH_ARGS
    RETVAL="$?"
    return "${RETVAL}"
}

do_stop()
{
    # Return
    # 0 if the daemon has been stopped
    # 2 if the daemon could not be stopped
    # other if a failure occured
    start-stop-daemon --stop --quiet --oknodo \
        --retry=TERM/5/KILL/5 \
        --pidfile $AUTOSSH_PIDFILE \
        --remove-pidfile
    RETVAL="$?"
    return "${RETVAL}"
}

do_restart()
{
    exit 0
}


case "$1" in
    status)
        if init_is_upstart; then
            exit 1
        fi
        status_of_proc -p "${AUTOSSH_PIDFILE}" "${AUTOSSH}" "${NAME}"
        ;;
    start)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Starting ${NAME}..."
        do_start
        log_end_msg "$?" # e.g. [ok], failed!, (warning)
        ;;
    stop)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Stopping ${NAME}..."
        do_stop
        log_end_msg "$?"
        ;;
    restart)
        if init_is_upstart; then
            exit 1
        fi
        log_begin_msg "Restarting ${NAME}"
        do_restart
        log_end_msg "$?"
        ;;
    force-reload)
        exit 0
        ;;
    *)
        log_failure_msg "Usage: service ${NAME} {status|start|stop|restart}"
        ;;
esac

Comment Conventions for Init Scripts

Reference: Comment Conventions for Init Scripts

### BEGIN INIT INFO
# Provides:          scriptname
# Required-Start:    $network
# Required-Stop:     $network
# Should-Start:      cgroup-lite
# Should-Stop:       cgroup-lite
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: short_description
# Description:       multiline_description
### END INIT INFO
  • 以上注释必须在以下两行分隔符内
    ### BEGIN INIT INFO
    ### END INIT INFO
    
  • 前后两行分隔符内的注释要以 # 开头,并且后面至少要跟着一个空格。(Description 除外,Description注释可以是多行描述。)
    # {keyword}: arg1 [arg2 ...]
    
    • Provides: boot_facility_1 [boot_facility_2 ...]
      Boot facilities provided by this init script. 该脚本要启动的服务的名称。
    • Required-Start: boot_facility_1 [boot_facility_2 ...]
      Facilities which must be available during startup of this service. The init-script system should insure init scripts which provide the Required-Start facilities are started before starting this script. 启动该脚本服务的依赖设备。
    • Required-Stop: boot_facility_1 [boot_facility_2 ...]
      Facilities which must be available during the shutdown of this service. The init-script system should avoid stopping init scripts which provide the Required-Stop facilities until this script is stopped. 关闭该脚本服务的依赖设备。
    • Should-Start: boot_facility_1 [boot_facility_2 ...]
      Facilities which, if present, should be available during startup of this service. This allows for weak dependencies which do not cause the service to fail if a facility is not available. 启动该脚本服务应该提供的依赖,如果没有,也不会造成启动服务失败。
    • Should-Stop: boot_facility_1 [boot_facility_2]
      Facilities which should be available during shutdown of this service. 关闭该脚本服务应该提供的依赖。
    • Default-Start: run_level_1 [run_level_2 ...]
    • Default-Stop: run_level_1 [run_level_2 ...]
      which run levels should by default run the init script with a start (stop) argument to start (stop) the services controlled by the init script. 该脚本服务的运行等级(0~6)。
      Run Level:

      • 0: halt
      • 1: single user mode.
      • 2: multiuser with no network services exported.
      • 3: normal/full multiuser.
      • 4: reserved for local user, default is normal/full multiuser
      • 5: multiuser with a display manager or equivalent
      • 6: reboot
    • Short-Description: short_description
      Provide a brief description of the actions of the init script. Limited to a single line of text. 脚本服务简述,只能够为一行。
    • Description: multiline_description
      Provide a more complete description of the actions of the init script. May span mulitple lines. In a multiline description, each continuation line shall begin with a # followed by tab character or a # followed by at least two space characters. The multiline description is terminated by the first line that does not match this criteria. 脚本服务的详细描述,可以分为多行。多行描述的时候,第二行开始每一行必须要 # 开头接着一个 tab 或者至少两个空格。
  • Facility Names
    Boot facilities are used to indicate dependencies in initialization scripts, as defined in Comment Conventions for Init Scripts. Facility names are assigned to scripts by the Provides: keyword. Facility names that begin with a dollar sign ($) are reserved system facility names.

    Note: Facility names are only recognized in the context of the init script comment block and are not available in the body of the init script. In particular, the use of the leading $ character does not imply system facility names are subject to shell variable expansion, since they appear inside comments.

    • $local_fs: all local file systems are mounted.
    • $remote_fs: all remote file systems are available. In some configurations, file systems such as /usr may be remote. Many applications that require $local_fs will probably also require $remote_fs.
    • $network: basic networking is available. Example: a server program could listen on a socket.
    • $named: IP name-to-address translation, using the interfaces described in this specification, are available to the level the system normally provides them. Example: if a DNS query daemon normally provides this facility, then that daemon has been started.
    • $portmap: daemons providing SunRPC/ONCRPC portmapping service as defined in RFC 1833: Binding Protocols for ONC RPC Version 2 (if present) are running.
    • $syslog: system logger is operational.
    • $time: the system time has been set, for example by using a network-based time program such as ntp or rdate, or via the hardware Real Time Clock.

The comment conventions described are only required for init scripts installed by conforming applications. Conforming runtime implementations are not required to use this scheme in their system provided init scripts.

Init Script Functions

Reference: Init Script Functions

. /lib/lsb/init-functions

Each conforming init script shall execute the commands in the file /lib/lsb/init-functions in the current environment (see shell special built-in command dot).

  • init_is_upstart: If the currently running init daemon is upstart, return zero; if the calling init script belongs to package which also provides a native upstart job, it should generally exit non-zero in this case.
  • status_of_proc: Return LSB status.
    • $1: daemon,init script 启动的进程
    • $2: 进程名称
    • -p: optional, daemon 的 pid 文件
     status_of_proc -p "/var/run/nginx.pid" "/usr/bin/nginx" "nginx"
    
  • log_begin_msg: 记录并打印信息,一般用在执行某个操作的开始位置,记录信息可以在 /var/log/syslog 查看,int log_begin_msg (char *message),传入值是一个信息字符串.
    log_begin_msg  "Starting autossh..."
    
  • log_end_msg: int log_end_msg (int exitstatus),传入值是一个整型的退出状态值,根据状态值返回:[ok], failed!, (warning) 等等。
    start-stop-daemon --start ...
    log_end_msg "$?"
    
  • log_success_msg, log_failure_msg, log_warning_msg
    更多函数说明可以查看 /lib/lsb/init-functions

Init Script Actions

Reference: Init Script Actions

Init scripts provided by conforming applications shall accept a single argument which selects the action:

  • start: Start the service
  • stop: Stop the service
  • restart: Stop and restart the service if the service if already running, otherwise start the service.
  • try-restart: Restart the service if the service is already running.
  • reload: Cause the configuration of the service to be reloaded without actually stoping and restarting the service.
  • force-reload: Cause the configuration to be reloaded if the service support this, otherwise restart the service if it is running.
  • status: Print the current status of the service.

The start, stop, restart, force-reload and status actions shall be supported by all init scripts; the reload and try-restart actions are optional. Other init-scripts actions may be defined by the init script.

case "$1" in
    status)
        exit 0
        ;;
    start)
        exit 0
        ;;
    stop)
        exit 0
        ;;
    restart)
        exit 0
        ;;
    force-reload)
        exit 0
        ;;
    *)
        log_failure_msg "Usage: service ${NAME} {status|start|stop|restart}"
        ;;
esac

Installation and removal of Init Scripts

Reference: Linux – 管理系统服务

  • CentOS
    Redhat 提供了 chkconfig 命令来管理系统的服务:

    • chkconfig --list:所有服务列表
    • chkconfig --list serviceName:只显示 serverName 服务
    • chkconfig serviceName on:开启 serverName 服务的自动启动
    • chkconfig serviceName off:关闭 serverName 服务的自动启动
    • chkconfig --add serviceName:添加服务
    • chkconfig --del serviceName:删除服务
  • Ubuntu
    Ubuntu 是没有 chkconfig 命令的,而是提供了另外的命令来实现管理服务:

    • sudo update-rc.d serviceName defaults:添加服务,默认添加服务为自动启动,即 /etc/rc0.d//etc/rc6.d 各级别里面都添加了服务的启动软链接。
    • sudo update-rc.d serviceName remove:删除服务,默认会删除所有级别的服务,即彻底删除服务。

      如果,你想要配置各级别的启动情况,可以删除相应级别目录里面的服务软链接。

    • systemctl daemon-reload:修改过服务之后,用该命令来重新加载服务。