Linux 如何连接着 Wi-Fi 的同时创建热点?
关注者
108被浏览
9,5274 个回答
这个方法有一个缺点,要先执行脚本开了热点后再联网。先联网那个脚本就启动不了了不知道为什么。
首先需要网卡支持ap模式;需要电脑上先装有这些:
楼主应该懂一些简单shell吧,有人写好了一个creat_ap脚本,都不难,你大看看看就知道怎么回事。参考:Software access point (简体中文)
1. 脚本
2. creat_ap文件内容
首先需要网卡支持ap模式;需要电脑上先装有这些:
# dependencies:
# bash (to run this script)
# util-linux (for getopt)
# hostapd
# dnsmasq
# iptables
# iproute2
# haveged (optional)
楼主应该懂一些简单shell吧,有人写好了一个creat_ap脚本,都不难,你大看看看就知道怎么回事。参考:Software access point (简体中文)
1. 脚本
#!/bin/bash
# 增加一个虚拟网络接口并设置一个mac地址
sudo iw dev wlp9s0 interface add wlp9s0_ap type __ap
sudo ip link set dev wlp9s0_ap address 04:e2:b9:17:18:72
# 注意creat_ap脚本的位置,系统要能找到,吧creat_ap文件丢到 /bin 里去吧
sudo creat_ap -c 11 wlp9s0_ap wlp9s0 youssid yourpasswowd
2. creat_ap文件内容
#!/bin/bash
# dependencies:
# bash (to run this script)
# util-linux (for getopt)
# hostapd
# dnsmasq
# iptables
# iproute2
# haveged (optional)
usage() {
echo "Usage: $(basename $0) [options] <wifi-interface> <interface-with-internet> <access-point-name> [<passphrase>]"
echo
echo "Options:"
echo " -h, --help Show this help"
echo " -c <channel> Channel number (default: 1)"
echo " -w <WPA version> Use 1 for WPA, use 2 for WPA2, use 1+2 for both (default: 1+2)"
echo " -g <gateway> IPv4 Gateway for the Access Point (default: 192.168.12.1)"
echo " -d DNS server will take into account /etc/hosts (default: disabled)"
echo
echo "Example:"
echo " $(basename $0) wlan0 eth0 MyAccessPoint MyPassPhrase"
}
get_macaddr() {
ip link show "$1" | sed -n 's/.*ether \([0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]:[0-9a-f][0-9a-f]\) .*/\1/p'
}
ARGS=$(getopt -o hc:w:g:d -l "help" -n $(basename $0) -- "$@")
[[ $? -ne 0 ]] && exit 1
eval set -- "$ARGS"
CHANNEL=1
GATEWAY=192.168.12.1
WPA_VERSION=1+2
ETC_HOSTS=0
while :; do
case "$1" in
-h|--help)
usage
exit 1
;;
-c)
shift
if [[ -n "$1" ]]; then
CHANNEL="$1"
shift
fi
;;
-w)
shift
if [[ -n "$1" ]]; then
WPA_VERSION="$1"
shift
fi
;;
-g)
shift
if [[ -n "$1" ]]; then
GATEWAY="$1"
shift
fi
;;
-d)
shift
ETC_HOSTS=1
;;
--)
shift
break
;;
esac
done
if [[ $# -ne 3 && $# -ne 4 ]]; then
usage
exit 1
fi
WIFI_IFACE=$1
INTERNET_IFACE=$2
SSID=$3
PASSPHRASE=$4
if [[ $(id -u) -ne 0 ]]; then
echo "You must run it as root."
exit 1
fi
CONFDIR=$(mktemp -d /tmp/create_ap.${WIFI_IFACE}.conf.XXXXXXXX)
echo "Config dir: $CONFDIR"
# hostapd config
cat << EOF > $CONFDIR/hostapd.conf
ssid=${SSID}
interface=${WIFI_IFACE}
driver=nl80211
hw_mode=g
channel=${CHANNEL}
ctrl_interface=$CONFDIR/hostapd_ctrl
ctrl_interface_group=0
EOF
if [[ -n "$PASSPHRASE" ]]; then
[[ "$WPA_VERSION" == "1+2" || "$WPA_VERSION" == "2+1" ]] && WPA_VERSION=3
cat << EOF >> $CONFDIR/hostapd.conf
wpa=${WPA_VERSION}
wpa_passphrase=$4
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP
EOF
fi
# dnsmasq config (dhcp + dns)
cat << EOF > $CONFDIR/dnsmasq.conf
interface=${WIFI_IFACE}
bind-interfaces
dhcp-range=${GATEWAY%.*}.1,${GATEWAY%.*}.254,255.255.255.0,24h
dhcp-option=option:router,${GATEWAY}
EOF
[[ $ETC_HOSTS -eq 0 ]] && echo no-hosts >> $CONFDIR/dnsmasq.conf
# enable interface
ip link set down dev ${WIFI_IFACE}
ip addr flush ${WIFI_IFACE}
ip link set up dev ${WIFI_IFACE}
ip addr add ${GATEWAY}/24 dev ${WIFI_IFACE}
# enable NAT
iptables -t nat -A POSTROUTING -o ${INTERNET_IFACE} -j MASQUERADE
iptables -A FORWARD -i ${WIFI_IFACE} -j ACCEPT
OLD_IP_FORWARD=$(cat /proc/sys/net/ipv4/ip_forward)
echo 1 > /proc/sys/net/ipv4/ip_forward
# boost low-entropy
if [[ $(cat /proc/sys/kernel/random/entropy_avail) -lt 1000 ]]; then
which haveged > /dev/null 2>&1 && {
haveged -w 1024 -p $CONFDIR/haveged.pid
}
fi
# start dns + dhcp server
dnsmasq -C $CONFDIR/dnsmasq.conf -x $CONFDIR/dnsmasq.pid
# start access point
echo "hostapd command-line interface: hostapd_cli -p $CONFDIR/hostapd_ctrl"
hostapd $CONFDIR/hostapd.conf || {
echo
echo "Hostapd failed to run, maybe a program is interfering."
echo "If you use NetworkManager then add the following in"
echo "/etc/NetworkManager/NetworkManager.conf and retry."
echo "Don't forget to remove it after you finish."
echo
echo "[keyfile]"
echo "unmanaged-devices=mac:$(get_macaddr "$WIFI_IFACE")"
echo
}
# exiting
for x in $CONFDIR/*.pid; do
kill -9 $(cat $x)
done
rm -rf $CONFDIR
iptables -t nat -D POSTROUTING -o ${INTERNET_IFACE} -j MASQUERADE
iptables -D FORWARD -i ${WIFI_IFACE} -j ACCEPT
echo $OLD_IP_FORWARD > /proc/sys/net/ipv4/ip_forward
ip link set down dev ${WIFI_IFACE}
ip addr flush ${WIFI_IFACE}
exit 0
首先你的网卡要支持ap模式而不是adhoc,然后直接在网络管理器里面配置一下就可以了,如果是纯命令行请务必关掉网络管理器,否则一些设置不会生效,说起来就是,1.设定sysctl,ipv4_forwarding神马的等于1; 2,增加一个网络接口,注意是网络接口。3,设定iptables