网络访问软件
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
-
无法从Linux主机免密登录Windows主机:Windows 10 v1809之后的OpenSSH服务器定义了以下配置,用于管理员用户登录。
# sshd_config Match Group administrators AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
解决方法:
- 使用非管理员用户登录;
- 注释上述配置项,恢复默认在用户目录下读取用户的公钥(推荐);
- 将管理员用户的公钥添加到
%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
会在远端建立一个监听套接字以转发其接收的请求到本地。
常见问题
-
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.0 | HTTP 1.0,`http1.1 |
-1,--tlsv1 | 使用TLS,`tlsv1.0 |
`--ssl,-2 | 3` |
-u,--user user:password | 提供服务器用户名和密码 |
-E,--cert CERT | CERT=certificate[:password] |
-#,--progress-bar | 传输进度显示为进度条 |
-Z,--parallel | 并发传输 |
`-4 | 6,--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}
。
下载
上传
HTTP
HTTP with curl - Everything curl
HTTP方法
默认为GET
,添加-d,-F
选项则默认为POST
,-T
则默认为HEAD
,-T
默认为PUT
。
-X,--request COMMAND
:COMMAND=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
Qv2ray
在==分组==中编辑订阅信息:

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

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
无法认证上网。
-
编辑网络接口配置
根据网络状况分别设置WAN口的IP地址获取方式(手动配置或DHCP),LAN口设置固定IP地址。
-
如果需要为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
。 -
==启用防火墙==并配置转发规则。
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连接至主机host1
;eth1
使用网桥连接至主机host1
(与物理网络其他主机连通);- 按上述方法配置软件路由;
- 将
host2
的默认网关设置为eth1
的IP地址;- 将
eth1
的默认网关设置为自己的IP地址(如果设置为物理网络的网关会导致eth1
向host2
发送网关重定向)。
虚拟机的路由表内容如下:
# 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
路由失效解决方案
- 主机无法访问通过软路由访问其他虚拟主机:可能是主机网络问题,重启虚拟机和主机。