I have decided to improve this answer in a more generic way so it may not answer this question exactly anymore. For a more up to date solution please look at
How to setup an unprotected Ad Hoc (IBSS) Network and if possible with WPA encryption?.
I have tried to implement this with systemd-networkd because it is consistent and straightforward and not a mix up of conflicting different network managers. I will give this answer as an alternative.
For reference I use a RPi3B+ with Raspbian Stretch Lite 2018-06-27 from scratch. directory. We need untouched interfaces to configure them otherwise we may get error messages.-->
Step 1: setup systemd-networkd
For detailed information look at [1]. Here only in short. Execute these commands:
rpi ~$ sudo -Es
rpi ~# mkdir -p /var/log/journal
rpi ~# systemd-tmpfiles --create --prefix /var/log/journal
rpi ~# systemctl mask networking.service
rpi ~# systemctl mask dhcpcd.service
rpi ~# sudo mv /etc/network/interfaces /etc/network/interfaces~
rpi ~# sed -i '1i resolvconf=NO' /etc/resolvconf.conf
rpi ~# systemctl enable systemd-networkd.service
rpi ~# systemctl enable systemd-resolved.service
rpi ~# ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
Configure the interfaces and create this two files. Give it your own ip addresses:
rpi ~# cat > /etc/systemd/network/08-wlan0.network <<EOF
[Match]
Name=wlan0
[Network]
Address=192.168.1.2/24
EOF
rpi ~# cat > /etc/systemd/network/12-wlan1.network <<EOF
[Match]
Name=wlan1
[Network]
DHCP=ipv4
EOF
Step 2: setup managed connection to the LAN for wlan1
Setup wpa_supplicant with this file and your settings (ssid, psk) and enable it:
rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan1.conf <<EOF
country=DE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="[email protected]"
psk="realyNotMyPassword"
}
EOF
rpi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan1.conf
rpi ~# systemctl disable wpa_supplicant.service
rpi ~# systemctl enable [email protected]
Reboot and check connection with upgrade. Reboot again if there are drivers updated:
rpi ~$ sudo apt update
rpi ~$ sudo apt full-upgrade
Step 3A: setup unprotected ad-hoc interface using systemd unit
Alternative you can use wpa_supplicant for this (see Step 3B). To configure the wifi into ad-hoc mode we only have to execute two commands (don't do that now):
iw wlan0 set type ibss
iw wlan0 ibss join RPiNet 2432 # <-frequency
I do this with a systemd unit so we can also stop the service. Create a new unit file with:
rpi ~$ sudo -Es
rpi ~# systemctl --force --full edit [email protected]
In the editor insert these statements, save it and quit the editor:
[Unit]
Description=create unprotected ad-hoc interface
Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
Wants=network.target
Before=network.target
[Service]
Environment="SSID=RPiNet" "FREQUENCY=2432"
#EnvironmentFile=/usr/local/etc/wifi-adhoc.conf
Type=oneshot
RemainAfterExit=yes
ExecStart=/sbin/iw %I set type ibss
ExecStartPost=/sbin/iw %I ibss join $SSID $FREQUENCY
ExecStop=/sbin/iw dev %I ibss leave
ExecStopPost=/sbin/iw %I set type managed
[Install]
WantedBy=multi-user.target
Enable the service:
rpi ~# systemctl enable [email protected]
reboot.
Check with:
rpi ~$ iw dev
rpi ~$ iw dev wlan0 link
rpi ~$ ip addr
rpi ~$ iw dev wlan1 scan | grep -B8 -A3 "SSID: RPiNet"
You should be able to:
rpi ~$ sudo systemctl stop [email protected]
rpi ~$ sudo systemctl start [email protected]
To change the ssid and frequency you can edit the unit file:
rpi ~$ sudo systemctl --full edit [email protected]
Alternative you can use a config file. Then use EnvironmentFile=
instead of Environment=
in the unit and create a config file like:
rpi ~# cat > /usr/local/etc/wifi-adhoc.conf <<EOF
SSID=RPiNet
FREQUENCY=2432
EOF
For mapping frequency to channel look at List of WLAN channels. Btw. frequency 2432 is channel 5.
Step 3B: setup unprotected ad-hoc interface using wpa_supplicant
Setup wpa_supplicant with this file and your settings (ssid, psk) and enable it:
rpi ~$ sudo -Es
rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
country=DE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
# use 'ap_scan=2' on all devices connected to the network
# this is unnecessary if you only want the network to be created when no other networks are available
ap_scan=2
network={
ssid="RPiNet"
frequency=2432
mode=1
key_mgmt=NONE
}
EOF
1pi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
rpi ~# systemctl disable wpa_supplicant.service
rpi ~# systemctl enable [email protected]
I have found that the wpa_supplicant.service uses driver nl80211
by default. But it cannot handle ad-hoc mode (see developer section). We have to use driver wext
. To modify the service we create a drop-in file:
rpi ~# systemctl edit [email protected]
In the editor insert these statements, save it and quit the editor:
[Service]
ExecStart=
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dwext -i%I
reboot.
Check with:
rpi ~$ iw dev
rpi ~$ iw dev wlan0 link
rpi ~$ ip addr
rpi ~$ iw dev wlan1 scan | grep -B8 -A3 "SSID: RPiNet"
For developers and for troubleshooting
I have tried to setup a secured ad-hoc wifi network using encryption with WPA/WPA2 without success. But this are some things I have done to find the answer. I do not want to discard them because it has taken some time and it may help me later and others on similar issues.
manual setup
For testing how it works you can execute these commands [2]. Be sure the interface isn't occupied by another service:
rpi ~$ sudo -Es
rpi ~# iw wlan0 set type ibss
rpi ~# ip link set wlan0 up
rpi ~# iw wlan0 ibss join RPiNet 2432
rpi ~# ip addr add 192.168.1.2 dev wlan0
rpi ~# ip route add 192.168.1.0/24 dev wlan0 proto kernel scope link src 192.168.1.2
rpi ~# exit
rpi ~$ # check with:
rpi ~$ iw dev
rpi ~$ iw dev wlan0 link
rpi ~$ ip addr
rpi ~$ sudo iw dev wlan1 scan | grep -B8 -A3 "SSID: RPiNet"
You can do this also on a second raspi with another ip address, e.g. 192.168.1.3. Then you can ping it.
unusable driver nl80211
On testing with wpa_supplicant using ad-hoc mode I always get a strange initialization that looks like this:
rpi ~$ iw dev
phy#0
Unnamed/non-netdev interface
wdev 0x2
addr 86:50:89:38:f2:93
type P2P-device
txpower 31.00 dBm
Interface wlan0
ifindex 3
wdev 0x1
addr b8:27:eb:06:e8:8b
type managed
channel 34 (5170 MHz), width: 20 MHz, center1: 5170 MHz
txpower 31.00 dBm
When you get this Unnamed/non-netdev interface
(type P2P-device) then you have a problem. It occupies the interface. When trying to iw wlan0 set type ibss
I got the error messages:
Jul 07 22:06:17 wpa_supplicant[262]: nl80211: Failed to set interface into IBSS mode
Jul 07 22:06:17 wpa_supplicant[262]: wlan0: Association request to the driver failed
Looking with systemctl cat [email protected]
you can see that wpa_supplicant is using first driver nl80211
and then driver wext
. This is given by parameter -Dnl80211,wext
rpi ~$ systemctl cat [email protected] | grep '^ExecStart='
ExecStart=/sbin/wpa_supplicant -c/etc/wpa_supplicant/wpa_supplicant-%I.conf -Dnl80211,wext -i%I
I found using driver wext
avoids this unnamed interface. So we have to use a drop-in file to change the parameter to -Dwext
.
setup wpa_supplicant with encryption
Now I tried to establish safe ad-hoc connections with encryption but I run into serious trouble. I found it on arch linux [2] and on:
rpi ~$ zcat /usr/share/doc/wpa_supplicant/examples/wpa_supplicant.conf.gz | grep -A10 '^# IBSS/ad-hoc network with RSN'
Setup wpa_supplicant with this file and your settings (ssid, psk) and enable it:
rpi ~$ sudo -Es
rpi ~# cat > /etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<EOF
country=DE
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
# use 'ap_scan=2' on all devices connected to the network
# this is unnecessary if you only want the network to be created when no other networks are available
ap_scan=2
network={
ssid="RPiNet"
key_mgmt=WPA-PSK
proto=RSN
psk="verySecretPassword"
mode=1
frequency=2432
pairwise=CCMP
group=CCMP
}
EOF
1pi ~# chmod 600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
rpi ~# systemctl disable wpa_supplicant.service
rpi ~# systemctl enable [email protected]
Create a drop-in file as shown unter Step 3B above.
For encryption we need random numbers and we can get error messages like:
wpa_supplicant[262]: random: Cannot read from /dev/random: Resource temporarily unavailable
wpa_supplicant[262]: random: Only 18/20 bytes of strong random data available from /dev/random
wpa_supplicant[262]: random: Not enough entropy pool available for secure operations
wpa_supplicant[262]: WPA: Not enough entropy in random pool to proceed - reject first 4-way handshake
Fortunately the Raspberry Pi has a hardware random generator but to use it we have to install a driver:
rpi ~# apt install rng-tools
reboot.
The problem here is that the interface wlan0 is configured and up but systemctl status [email protected]
gives me an error message:
wlan0: CTRL-EVENT-EAP-FAILURE EAP authentication failed
I don't know why. I cannot ping another ad-hoc configured raspi. There is no connection established. It was also reported that there is a problem when there is another raspi in ad-hoc mode and tries to connect [5]. If anyone has an idea how to fix one of these issues please give me a comment under this answer.
refefences:
[1] Howto migrate from networking to systemd-networkd with dynamic failover
[2] Ad-hoc networking
[3] List of WLAN channels
[4] Raspberry Pi 2018-04-18 - Cannot put device into adhoc mode
[5] Kernel trace in brcmfmac wifi driver when joining ad-hoc network w/another brcmfmac device
[6] Linux WiFi Ad-hoc mode
sudo systemctl disable dhcpcd.service
, reboot and use networking with/etc/network/interfaces
.dhcpcd <interfacename>
from the command line, it connects to the DHCP server and gets an IP address. After this I have the expected network connectivity, though the WiFi icon still says "connection to dhcpcd lost".raspi-config
to try to setup a WiFi connection (option N2 Wi-fi), I get the error messageCould not communicate with wpa_supplicant
.