Linux 二三事 - 开机自启动的热点

用户 Passthem 的头像
Passthem
2025 年 2 月 20 日 更新

虽然 Linux 有很高的可定制性,但是对我这样的小白来说,要实现一些听起来很容易的事情实际上没那么容易。我这次的需求就是,我希望能够开机自启动热点。

原因是这样的,我在家,我的电脑,或者我平时用手机,都是在房间里面。房间有一条网线牵引,而无线网络的信号很差。所以,我需要开热点,才能在我的房间以比较合理的速度上网。

graph TD;
  A[家庭网络] -->|有线连接| B[我的电脑]
  B -->|无线连接| C[我的手机]
  B -->|无线连接| C[香橙派等设备]

把热点开起来

我不打算介绍图形界面的操作方法,因为「仅仅在图形界面操作」的话,确实不太能直接设置开机启动。所以,就要知道怎么用命令配置启动热点:

sudo nmcli dev wifi hotspot ifname wlo1 con-name Hotspot \
    ssid Aquarius password "xxxxxxxx"

我使用的是 NetworkManager 来管理网络,如果你要自己复现,只用把 ssid 后面的 Aquarius 换成自己的热点名字,而 password 换成热点的密码就好了。

这样只创建了一条「连接」的配置,没有启动它,所以还需要手动启动它:

sudo nmcli con up Hotspot

让热点能用

这样,理论上我们就能上网了,但对我的环境,我手机直接连接上去,会显示上不了网。实际上,中间有两个因素阻拦。一个是防火墙,一个是 IP 转发规则。

先说说 IP 转发。现在的状况是,手机连接上了热点,确实跟电脑连上了。但是电脑没有配置 IP 转发规则,也就是说,手机发了数据包,电脑不知道转发给谁。手机看发的数据包都没人回答,那肯定是连不上网了。

所以先配置转发规则:

# 设置将热点的网段(10.42.0.0/24)使用 NAT 转发
# 转发的目标是有线网络连接设备 enp4s0
# MASQUERADE 可以通俗理解成「
#     你的电脑就像一个路由器一样,
#     或者说,像一个邮局一样,
#     负责揽收所有网络数据,从同一个地址寄送出去,
#     往上一级的网络收到返回值以后,寄回这个邮局,
#     然后邮局再把数据包交给你。
# 」
sudo iptables -t nat -A POSTROUTING -s 10.42.0.0/24 -o enp4s0 -j MASQUERADE

# wlo1 是我的无线网络的网络设备,而 enp4s0 正如上文所说,
# 是我的有线网络的网络设备。
# 这条规则允许从 wlo1 的网络数据传输到 enp4s0
sudo iptables -I FORWARD -i wlo1 -o enp4s0 -j ACCEPT

# 这条规则允许从 enp4s0 的回复用的网络数据回传到 wlo1
sudo iptables -I FORWARD -i enp4s0 -o wlo1 \
    -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

但除此之外,还有一个 firewalld 的防火墙拦住了,所以无奈之下只能禁用它:

sudo systemctl stop firewalld.service      # 停止
sudo systemctl disable firewalld.service   # 取消开机启动

这样以后,我的手机就能上网了。

让热点开机启动

开机启动配置的是一个 systemd 服务。先创建一个脚本,把前面的这些工作都写上来。这个脚本我存到了 /usr/local/bin/my_start.sh 里面。

#!/bin/bash

iptables -t nat -A POSTROUTING -s 10.42.0.0/24 -o enp4s0 -j MASQUERADE
iptables -I FORWARD -i wlo1 -o enp4s0 -j ACCEPT
iptables -I FORWARD -i enp4s0 -o wlo1 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

nmcli dev wifi hotspot ifname wlo1 con-name Hotspot ssid Aquarius password "xxxxxxxx"
nmcli con up Hotspot

然后写一个 systemd 的配置文件,我写到了 /etc/systemd/system/my_startup.service 里面,实际上,启动脚本应该要放到这个文件夹里面:

[Unit]
Description=PT Startup Script
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=root
ExecStart=/usr/local/bin/my_startup.sh

[Install]
WantedBy=multi-user.target

其中我规定了 User 是 root,这个启动脚本应该由 root 来运行。毕竟前面我们手动执行的时候,都用了 sudo

最后启用它就好了:

sudo systemctl enable my_startup.service
sudo systemctl start my_startup.service

这样,热点就可以开机启动了。

评论区