网络访问软件

SSH

SSH可以通过终端或Web终端远程访问Linux服务器,也可以使用X Window访问服务器的图形界面应用。使用SSH访问服务器需要在服务器上安装openssh-server

ssh -p SSH_PORT [user@]host
    -4/6   # ipv4/ipv6 only
    -b ip_addr

通过中间节点登录远程主机:

ssh -J [user@]host[:port] user@host  # connect via a jump host

中间节点需要与目的节点建立连接,因此如果目的节点使用主机名,则需要在中间节点上配置目的节点的“主机名<->IP地址”映射。

SSH客户端配置文件

配置文件用于保存固定的SSH连接配置,以简化命令行输入参数。

HOST dev     # 远程地址匹配模式*
   HostName dev.example.com
   User gary

当SSH的目标非user@host形式,则客户端逐次匹配HOST指定的模式,并将匹配模式下的SSH连接配置应用于当前连接请求。如果有多个模式匹配成功,==重复出现的配置项被忽略==(先出现的配置项优先级高)。

*:可使用通配符*?,可对模式添加前缀!表示反向匹配;

服务器身份记录

当客户端尝试SSH连接远程服务器时,服务器会提供一个身份识别信息(ECDSA key指纹)让客户端确认。当客户端确认后,该服务器地址和对应的身份信息被保存到.ssh/known_hosts中。如果服务器发生变更导致其提供的身份识别信息发生变化,则会产生*Host key verification failed*错误。要解决此问题,只需从.ssh/known_hosts中删除对应服务器的记录(错误信息提示该记录所在的行号)。

SSH配置问题

  • root账户无法通过SSH登录,其他账户可以。原因:SSH配置不允许root登录,修改配置(/etc/ssh/sshd_config):

    #PermitRootLogin prohibit-password
    #PubkeyAuthentication yes
    PermitRootLogin yes  #*
    

    *:允许root远程登录存在较大安全隐患,使用密码登录风险更大(已知密码可在任意可访问服务器的机器上登录)。将该选项设置为prohibit-password并设置使用公钥验证,则只有预先在远程机器上配置了客户端的公钥,才能在相应客户端上登录root账户。

  • 由于SELinux的安全策略,Fedora/CentOS非root账户仍无法自动登录,需要修改目标主机下的目录.ssh及文件.ssh/authorized_keys的权限。

    chmod 0700 ~/.ssh                  # rwx------
    chmod 0600 ~/.ssh/authorized_keys  # rw-------
    
  • 无法使用密码进行远程登录(出现publickey错误)。原因:sshd的配置未开启密码验证(各发行版的默认配置可能不同,此问题出现在WSL上)。

    PasswordAuthentication yes
    ChallengeResponseAuthentication no
    UsePAM yes
    # 利用PAM管理使用者认证有很多好处,可以记录与管理。
    # 所以这里我们建议你使用 UsePAM 且 ChallengeResponseAuthentication 设定为 no 
    
  • blocked by Windows Terminal

  • 无法从Linux主机免密登录Windows主机:Windows 10 v1809之后的OpenSSH服务器定义了以下配置,用于管理员用户登录。

    # sshd_config
    Match Group administrators
           AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
    

    解决方法:

    1. 使用非管理员用户登录;
    2. 注释上述配置项,恢复默认在用户目录下读取用户的公钥(推荐);
    3. 将管理员用户的公钥添加到%PROGRAMDATA%\ssh\administrators_authorized_keys文件中。
  • client_loop: send disconnect: Connection reset,Windows终端长时间未操作自动断开与服务器的连接,修改终端配置

    ClientAliveInterval 60
    ClientAliveCountMax 5
    

    如果错误信息为Connection reset by peer,则可尝试修改服务端的对应配置:

    ServerAliveInterval 60
    ServerAliveCountMax 5
    

免密码登录

在远程主机保存登录用户的公钥。

ssh-keygen  # 在本地生成SSH的登录密钥
for node in '[user@]node1' 'node2' ...; do
 ssh-copy-id -i ~/.ssh/id_rsa.pub $node
done

ssh-keygen选项

-t rsa | dsa | ecdsa | ed25519:指定创建的密钥类型;

-b bits:密钥的长度。RSA密钥最小长度为1024,默认为2048;DSA密钥长度为1024;ECDSA密钥长度为256、384或521(椭圆曲线);Ed25519密钥长度为定值,该选项无效。

-C comment:添加注释。

-f filename:指定密钥文件(默认位于~/.ssh目录下)

-h:创建主机凭证而非用户凭证;

-e:读取一个OpenSSH公钥文件并以指定格式输出(-m RFC4756|PKCS8|PEM,默认格式为RFC4716)。

-F hostname:在known_hosts文件中搜索指定主机并列举。

-l:输出公钥文件的指纹,使用-E md5|sha256指定文件hash算法。

-R hostname:移除known_hosts中所有属于hostname的密钥。

从Windows主机免密登录Linux主机:

# Powershell at user home of Windows host
cat ~/.ssh/id_rsa.pub | ssh user@HOST 'mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

SSH远程执行命令

ssh user@remote_server "command1; command2; ./script"
ssh user@remote_server "command1;" "command2;" "./script"

可以提供多条命令,分隔的命令会在远端重组。

提升远端管理员权限

适用于Ubuntu等未开启root账号的系统,从远程执行管理命名需要提升管理员权限。此时需要使用-t选项使终端支持输入远程主机的密码。

ssh -t adminuser@host "sudo command"

远程执行命令时远程主机默认只提供基本环境变量(non-interactive,不会自动加载~/.bashrc文件)。为了自动加载~/.bashrc中的环境变量(不是.bash_profile.profile文件),在SSH配置文件/etc/ssh/sshd_config中启用:

sed -Ei 's/#(PermitUserEnvironment\s+)(no)/\1yes/' /etc/ssh/sshd_config

再次启动SSH会话后,新添加环境变量生效。

在Ubuntu(20.04)的.bashrc的开头有判断,如果是非交互式shell的语句(例如通过ssh远程执行的命令),则直接跳过后续初始化,因此需要把需要暴露给远端用户的变量置于该判断条件之前。

if [[ ! $PATH = *java* ]]; then
    export PATH=$PATH:$JAVA_HOME/bin
fi

允许root远程登录

# vi /etc/ssh/sshd_config
PermitRootLogin yes
# service sshd restart

通过SSH进行安全端口转发

本地通过SSH客户端与远程服务端口建立安全连接,利用SSH端口转发功能,用户只需访问本地SSH开放的端口即可访问远程服务。(使用前提是服务器开启SSH服务,且网络策略允许通过SSH访问服务器)

使用SSH建立隧道代理远端服务

ssh会在本地建立一个监听套接字local_addr:local_port以转发其接收的请求到远端的服务端口r_addr:r_port

ssh -N -L [local_addr]:local_port:r_addr:r_port USER@HOST  
# -N disables executing a remote shell

将远端访问请求转发至本地服务端口

ssh -N -R [r_addr:]r_port:local_addr:local_port USER@HOST

r_addr:远端地址,默认为环回地址,如果为空或*则表示所有地址。

ssh会在远端建立一个监听套接字以转发其接收的请求到本地。

常见问题

  1. SSH登录等待时间太长。

    原因:可能是SSH服务所在主机配置了DNS服务器地址,但对应的服务器不可用,导致DNS解析等待。

    解决方法:查看/etc/resolve.conf查看是否存在不可用的DNS服务器地址。如果有,修改网络接口的DNS配置并重启网络服务。

wget

HTTP, HTTPS, FTP和FTPS下载。

wget [option]... [URL]...

选项:

-c, --continue # Continue getting a partially-downloaded file. 
--limit-rate=amount  # Limit download speed
--user=user, --password=password # user/password if necessary
--ask-password
-P prefix, --directory-prefix=prefix  # base directory
-O --output-document=FILE # save download as FILE

如果所在网络的Web流量是经本地网络的代理转发的,需要wget配置本地代理(系统/etc/wgetrc或用户~/.wgetrc)。

https_proxy = http://USERNAME:PASSWORD@proxy.server.net:port/
http_proxy = http://proxy.server.net:port/
ftp_proxy = http://proxy.server.net:port/

或者通过环境变量配置代理

curl

curl [optiosn] url
选项说明
-H HEADER为请求添加头部信息
-d, --data <data> 上传数据体
JSON数据需要指定:Content-Type: application/json
-k,--insecure 允许非安全SSL
-I,--head仅返回响应头部
-L,--location跟踪重定向
-o,--output file输出内容到文件
-x,--proxy addr使用代理[protocol://]host[:port]
-0,--http1.0HTTP 1.0,`http1.1
-1,--tlsv1使用TLS,`tlsv1.0
`--ssl,-23`
-u,--user user:password提供服务器用户名和密码
-E,--cert CERTCERT=certificate[:password]
-#,--progress-bar传输进度显示为进度条
-Z,--parallel并发传输
`-46,--ipv4

信息展示

-v,--verbose:显示curl的处理过程;

-s,--silent: ==不输出传输过程的状态信息(仅输出响应数据)==;

-S,--show-error:在安静模式下仍能输出错误信息;

--trace dumpfile:将传输过程中输出的信息和接收的数据(十六进制编码)输出到文件中,使用-代替文件名以输出到标准输出。

--trace-ascii dumpfile:将数据以ASCII码方式存储;

--trace-time:在输出信息/数据前显示时间hours:minutes:seconds.microseconds

-w,--write-out MSG:在传输完成后输出信息,信息可以是简单字符串,文件内容@filename(标准输入@-),或是从接受数据中提取的字段%{variable_name}

下载

Downloads - Everything curl

上传

Uploads - Everything curl

HTTP

HTTP with curl - Everything curl

HTTP方法

默认为GET,添加-d,-F选项则默认为POST-T则默认为HEAD-T默认为PUT

-X,--request COMMANDCOMMAND=GET|POST|...

netcat

选项:

-s 10.1.2.3 # 指定源端IP
-p 31337    # 指定源端本地端口
-w 5        # 连接超时(秒)
-u          # 建立UDP连接

basic client-server model

nc -l [server_addr] port  # server
nc server_addr port       # client

建立连接后可双向通信(通过标准输入输出进行通信)。

远程Shell访问服务

rm -f /tmp/f; mkfifo /tmp/f  # remove the FIFO file when finished
cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f

nc从远程接收的数据被定向到管道;管道中的数据被cat读取作为sh的输入命令;执行命令的输出作为nc的输入由其转发给远端。(==该操作可让远端执行任何命令==)

数据传输

 nc -l 1234 > filename.out
 nc -N host.example.com 1234 < filename.in

访问基于文本协议的服务

printf "GET / HTTP/1.1\r\n\r\n" | nc www.baidu.com 80

端口扫描

nc -zv host.example.com 20-30 http

通过代理连接

nc -x10.2.3.4:8080 -Xconnect [-P<username>] host.example.com 42

代理

v2ray

v2rayN

Qv2ray

在==分组==中编辑订阅信息:

image-20220302162543149

在分组的订阅设置中输入订阅地址并选择订阅类型

image-20220302162622744

clash

初始化配置
wget -O ~/.config/clash/config.yaml $SUBSCRIBE_URL
COUNTRY_DB_URL=https://www.sub-speeder.com/client-download/Country.mmdb
wget -O ~/.config/clash/Country.mmdb $COUNTRY_DB_URL
配置前端web界面
git clone https://github.com/Dreamacro/clash-dashboard.git
cd clash-dashboard
git checkout -b gh-pages origin/gh-pages

编辑clash配置文件,设置界面的登录密码和网页资源地址。

secret: gang2019
external-ui: /home/gary/downloads/clash-dashboard

Clash的Web访问地址为:http://127.0.0.1:9090/ui/

启动服务
clash -d /home/gary/.config/clash/

设置为系统服务:

[Unit]
Description=Clash - a rule-based tunnel in Go.
Documentation=https://github.com/Dreamacro/clash
After=network.target network-online.target
[Service]
Type=simple
User=clash
Group=clash
WorkingDirectory=/home/clash
ExecStart=/usr/local/clash/clash -d /usr/local/clash/config
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=clash
ProtectSystem=true
[Install]
WantedBy=multi-user.target

设置Crontab规则以周期更新配置文件中的订阅信息。

sudo crontab -e  # 进入编辑模式
m  h  dom   mon dow  command
30 4  1,15  *   *    bash /home/gary/bin/clash.sh init $URL

软路由

主机具有多个网络接口,其中一个连接WAN(假设为eth0),其他作为LAN接口(eth1, eth2, ...,使用ifconfig查看网络接口信息)1

场景1:与可联网主机host1在同一网络的另一台设备host2无法认证上网。

  1. 编辑网络接口配置

    根据网络状况分别设置WAN口的IP地址获取方式(手动配置或DHCP),LAN口设置固定IP地址。

  2. 如果需要为LAN中的机器分配IP地址,则为LAN口配置DHCP服务器

    sudo apt install isc-dhcp-server
    sudo nano /etc/default/isc-dhcp-server 
    # configure interfaces for DHCP server
    # INTERFACESv4="eth1"	 # support multi-interfaces, "eth0 eth1".
    sudo nano /etc/dhcp/dhcpd.conf  # configure DHCP server...
    # after editing, start DHCP server
    sudo systemctl restart isc-dhcp-server
    sudo systemctl enable isc-dhcp-server
    # check the status of DHCP server
    sudo systemctl status isc-dhcp-server
    

    编辑DHCP服务器的配置文件(dhcpd.conf

    option domain-name "whatever.you.want";
    option domain-name-servers 223.5.5.5, 223.6.6.6;
    default-lease-time 600;
    max-lease-time 7200;
    ddns-update-style none;
    authoritative;
    log-facility local7;
    subnet 192.168.1.0 netmask 255.255.255.0 {
         range 192.168.1.101 192.168.1.200;
         option subnet-mask 255.255.255.0;
         option routers 192.168.1.1;
         option broadcast-address 192.168.1.255;
    }
    

    如果配置正确,则最后查看DHCP服务器状态,可以看到一行显示active

  3. ==启用防火墙==并配置转发规则。

    sudo ufw enable		
    sudo vi /etc/rc.local
    sudo chmod 755 /etc/rc.local  # make it executable, executed at boot time
    

    rc.local中配置防火墙的转发规则。

    #!/bin/bash
    LAN=eth1
    WAN=eth0
    # Default policy to drop all incoming packets.
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    # Accept incoming packets from localhost and the LAN interface.
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A INPUT -i $LAN -j ACCEPT
    # Accept incoming packets from the WAN if the router initiated the connection.
    iptables -A INPUT -i $WAN -m conntrack \
      --ctstate ESTABLISHED,RELATED -j ACCEPT
    # Forward LAN packets to the WAN.
    iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT
    # Forward WAN packets to the LAN if the LAN initiated the connection.
    iptables -A FORWARD -i $WAN -o $LAN -m conntrack \
      --ctstate ESTABLISHED,RELATED -j ACCEPT
    # NAT traffic going out the WAN interface.
    iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE
    exit 0  # rc.local needs to exit with 0
    

虚拟机解决方案

如果物理主机仅有单个网络接口,可使用虚拟机进行软件路由,可为虚拟机配置两个接口,一个用于连接宿主机NAT网络访问WAN,另一个用于桥接物理网络(转发其他机器的流量)。

  • 为虚拟机vm-router设置两张网卡:eth0使用NAT连接至主机host1eth1使用网桥连接至主机host1(与物理网络其他主机连通);
  • 按上述方法配置软件路由;
  • host2的默认网关设置为eth1的IP地址;
  • eth1的默认网关设置为自己的IP地址(如果设置为物理网络的网关会导致eth1host2发送网关重定向)。

虚拟机的路由表内容如下:

# vm router的路由表
Destination    Gateway        Genmask       ... Metric Iface
0.0.0.0        192.168.178.2  0.0.0.0             0    eth0  # 默认路由网关
172.28.76.0    0.0.0.0        255.255.255.0       0    eth1  # PHY net
192.168.178.0  0.0.0.0        255.255.255.0       0    eth0  # NAT net

路由失效解决方案

  1. 主机无法访问通过软路由访问其他虚拟主机:可能是主机网络问题,重启虚拟机和主机。

参考资料