Showing posts with label raspberry pi. Show all posts
Showing posts with label raspberry pi. Show all posts

Sunday, October 25, 2020

Raspberry Pi Bridge eth0 to wlan0 with wlan_kabel

I spent a ridiculous amount of time trying to persuade native Raspberry Pi OS to bridge the local ethernet port onto the WiFi segment. (turns out it is apparently not possible) 

My intention is having a remote device such as my Envox BB3 programmable power supply with only a wired ethernet connection, connect to my WiFi segment so that I can use EEZ Studio without needing to plug the BB3 into a wired ethernet port. The connection is the same as before:



In my prior blog, I came up with a somewhat brute-force method of setting up a local DHCP server and using dnsmasq. However, as brute force methods go, it was also neither a very graceful nor flexible solution.

While surfing the internet looking for alternatives, there was one person that casually mentioned "you can also try wlan_kabel". This turned out to be a ridiculously cool solution!

Starting with my default headless Raspberry Pi setup, install git and clone escitalopram's wlan_kabel. You'll need the MAC address of the device to use; the BB3 shows this on the ethernet settings screen:




sudo apt-get install git
git clone https://github.com/escitalopram/wlan_kabel.git
cd wlan_kabel
make

# the magic (showing the example MAC address from the docs)
# you'll need to put your own address here:
sudo ./wlan_kabel wlan0 eth0 74:69:69:2d:30:11

That's it! It just works. There are of course limitations (one device connected to Raspberry Pi eth0 port).

To run wlan_kabel at boot time, put this in /etc/rc.local :
(/home/pi/wlan_kabel/wlan_kabel wlan0 eth0 74:69:69:2d:30:11 > /dev/null 2>&1) &
Don't forget to use your own MAC address, and be sure to include the training ampersand.

This is a vastly more graceful solution. Just plug in the RPi and connect to the IP address shown, in my case 192.168.1.114 then connect:


  Et voilĂ !


Note the hard-wired ethernet port of the BB3 on the other wise of the Raspberry Pi has an IP address from the WiFi.

Raspberry Pi Network eth0 to wlan0 Router

Connecting ethernet wired-only equipment to WiFi.

TL;DR install dnsmasq, edit /etc/dnsmasq.conf to setup DHCP server and /etc/dhcpcd.conf to configure eth0, enable forwarding then manually set default routes.

There are lots of articles on using a Raspberry Pi as a WiFi AP (Access Point, aka "hotspot") and routing that traffic onto a wired eth0 connection: wlan0 to eth0. I want the opposite: take a Raspberry Pi STA (Station aka "client", already connected to some other WiFi) and route the local eth0 traffic into the wireless wlan0. Ideally, I'd like that eth0 to be bridged onto the WiFi network (DHCP relay onto eth0). Turns out that's not so easy. Google "can't add wlan0 to bridge br0: Operation not supported"

Why do this? Well, I started with my new Envox BB3 programmable power supply that has only a wired ethernet connection. What would it take to connect it via a Raspberry Pi to WiFi? Not as trivial of a matter as I had expected. 


To get started, see my prior blog on setting up a headless Raspberry Pi. 

This first operational example below uses somewhat of a brute-force method in using dhcpcd to manually configure the eth0 interface, and dnsmasq as a DHCP server. 

First, install dnsmasq
sudo apt-get install dnsmasq --assume-yes                               

Essential to the RPi acting as a forwarding router, edit the /proc/sys/net/ipv4/ip_forward file and ensure a value of 1 is there. Note that the change is immediate, although perhaps not permanent. Thanks to a comment on stackexchange, I found this to be very helpful:
grep -rn net.ipv4.ip_forward /etc/*                                  

In my case: /etc/sysctl.conf:28:#net.ipv4.ip_forward=1

Note the line is commented out. To make IP forwarding permanent, edit the /etc/sysctl.conf file to uncomment the net.ipv4.ip_forward=1 line.

Edit /etc/dnsmasq.conf and add these lines at the end to serve as a DHCP server on the RPi ethernet port:
#configure the eth0 interface
interface=eth0

# The three modes are "wildcard", "bind-interfaces" and "bind-dynamic".
bind-dynamic

# Never forward plain names (without a dot or domain part)
domain-needed

# Never forward addresses in the non-routed address spaces.
bogus-priv

# Set the NTP time server address to be the same machine as is running dnsmasq
dhcp-option=42,0.0.0.0

# enable the integrated DHCP server, you need to supply the range of 
# addresses available for lease and optionally a lease time
dhcp-range=192.168.42.50,192.168.42.59,255.255.255.0,12h

Edit /etc/dhcpcd.conf (see RPi docs and man page) and add these lines to assigned a fixed IP address to the RPi ethernet port:
interface eth0
static ip_address=192.168.42.10/24

# add the default route on the RPi on the line below. See command: 
# ip route | grep default
# static routers=192.168.42.10
static routers=192.168.42.10, 192.168.1.10

# Don't solicit or accept IPv6 Router Advertisements and DHCPv6
noipv6

# Don't solicit or accept IPv6 Router Advertisements.
noipv6rs

# ensure this route has a high metric to not use it for regular traffic
metric 900

Reboot the RPi.

Once everything is setup, a tiny bit of attention is needed to get routing working properly. This is because your default router does not "know" that a new network exists and is routed through a specific device interface. We need to know the IP address of the RPi that is now acting as router, shown here using the ifconfigcommand:

pi@raspberrypi:~$ ifconfig -a wlan0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.110  netmask 255.255.255.0  broadcast 192.168.1.255
My IP address in this case is 192.168.1.110, other WiFi IP addresses will likely be different.

The best way to set the new default route is at the WiFi router itself. Given the many different types of routers, there are as many methods of setting a new route. For dd-wrt, see static routing.

Alternatively, this can be done on a local workstation (in my case the one running EEZ Studio that I want to connect to the BB3); On Windows in an administrative privileges DOS command prompt. connected to the same network WiFi as the RPi configured above, we need to manually tell Windows how to find the new Raspberry Pi routed subnet with the DOS route command:

ROUTE [-f] [-p] [-4|-6] command [destination] [MASK netmask] [gateway] [METRIC metric] [IF interface]

In our case: route add [destination network] mask 255.255.255.0 [RPi address]:

route add 192.168.42.0 mask 255.255.255.0 192.168.1.110
  
This basically tells windows: hey, to find the 192.168.42.0 network, route via the address of our Raspberry Pi at 192.168.1.110

To confirm operation:
pi@raspberrypi:~$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.42.10  netmask 255.255.255.0  broadcast 192.168.42.255

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.110  netmask 255.255.255.0  broadcast 192.168.1.255

pi@raspberrypi:~$ route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         192.168.1.10    0.0.0.0         UG    303    0        0 wlan0
192.168.1.0     0.0.0.0         255.255.255.0   U     303    0        0 wlan0
192.168.42.0    0.0.0.0         255.255.255.0   U     900    0        0 eth0
And on Windows with the route print command (edited here, as I have VM's cluttering up the list):
C:\>route print
  
IPv4 Route Table
===========================================================================
Active Routes:
Network Destination        Netmask          Gateway       Interface  Metric
          0.0.0.0          0.0.0.0     192.168.1.10    192.168.1.140     50
      192.168.1.0    255.255.255.0         On-link     192.168.1.140    306
    192.168.1.140  255.255.255.255         On-link     192.168.1.140    306
    192.168.1.255  255.255.255.255         On-link     192.168.1.140    306
     192.168.42.0    255.255.255.0    192.168.1.110    192.168.1.140     51
  255.255.255.255  255.255.255.255         On-link     192.168.1.140    306
===========================================================================
Persistent Routes:
  None
 
If you see an error "Timeout (no response to IDN query)" in EEZ Studio, try rebooting the BB3



In the end, although this technically works - it is still not the simple solution I am looking forward. It is too annoying to find DHCP address (or manually configure a static one), and the fuss with manual routes. In my next blog, I test drive wan_kabel. It is pretty cool!


Resources, Inspiration, Credits, and Other Links:







Saturday, October 24, 2020

Raspberry Pi Headless Setup

Some notes on setting up a fresh Raspberry Pi.

TL;DR Edit 4 files on the SD card before initial powerup:
  • ssh (just create a blank one)
  • cmdline.txt (add option to disabled IPv6)
  • config.txt (edit to enable UART)
  • wpa_supplicant.conf (config to boot with WiFi working)

Newer versions of Raspian (now called Raspberry Pi OS) come with the Serial UART TTL and SSH disabled by default. Enable SSH by adding a file called SSH to the root directory. The Serial UART can be enabled as described in the Adafruit Headless Quick Start by adding a line to the config.txt file on the SD card before inserting into the RPi:

#enable pins 8 (TxD) and 10 (RxD) as serial TTY                               
enable_uart=1                                   

Reminder for Windows users: Microsoft continues to try to out-think you by automatically adding a ".txt" to files created when right-clicking in Explorer. Check the box "View - File name extensions" in Explorer or use the copy con: ssh command from a DOS prompt (Ctrl-Z to write the file)

The network can be configured in the wpa_supplicant.conf (new file created on SD card) as described in Setting up a wireless LAN via the command line by creating a file called wpa_supplicant.conf: (see docs)
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev                       
update_config=1
country=US
 
network={
    ssid="YOURSSID"
    psk=YOURPASSWORD
    scan_ssid=1
}

Some places will claim to not use quotes. I needed to use them around ssid, but not on psk.

The wpa_supplicant.conf file will be copied to /etc/wpa_supplicant/wpa_supplicant.conf and the removed from the boot directory at RPi startup time. cmdline.txt file and add ipv6.disable=1

If you want to use a psk instead of a plain text password, and for some reason don't have a linux box or WSL to run wpa_passphrase "YOURSSID" (installed with sudo apt install wpasupplicant) there's a Wireshark page that will do the conversion.

We'll also (optionally) install log2ram as described in my prior blog on the Pi-Hole notes.
sudo rfkill unblock wlan
sudo apt-get update
sudo-apt-get upgrade --assume-yes
sudo apt-get install fail2ban --assume-yes


# log2ram install (optional)
cd ~/
curl -Lo log2ram.tar.gz https://github.com/azlux/log2ram/archive/master.tar.gz
tar xf log2ram.tar.gz
cd log2ram-master
chmod +x install.sh && sudo ./install.sh
# REBOOT BEFORE INSTALLING ANYTHING ELSE

I saved these 4 files and simply copy them to the root of the CD card when burning a new image for a fresh Raspberry Pi setup.

Sunday, February 23, 2020

Raspberry Pi - pi-hole setup notes

In the category of "why didn't I do this sooner" - I finally setup my full network ad-blocking pi-hole. It's great! I can't believe I waited this long. The install is really quite straightforward for a basic system, however there are always options for fine tuning.

The basic install is quite good and blocks quite a bit of junk.

One of the places that has more extensive information on pi-hole options is this smart home beginner article, which ironically also features a ton of ads that are not blocked by a pi-hole default install. :/

When considering which device to run pi-hole on, consider the requirements. It does not have to be a Raspberry Pi, although that's nearly a perfect platform for most users. I ended up choosing a prior-generation Raspberry Pi 3 Model B+ for the lower power consumption and a Samsung 32GB microSDHC EVO, purchased separately.  Given my actual requirements, I probably should have chosen the Raspberry Pi 2, instead. (see below on power details)

My Raspberry Pi 3B+ has built-in WiFi and Bluetooth. Both are features that I will not likely use for my pi-hole. I prefer the reliability (and security) of a wired Ethernet connection for something as important as DNS lookups.

One of the benefits of the 3B+ is that the official Raspberry Pi PoE HAT can be used to power the Raspberry Pi over Ethernet. I didn't go this route.

Update: see my blog on Raspberry Pi Headless Setup. I've found setting up those 4 pre-configured files and copying them to the root of SD card at image-write-time is quite handy and gets the RPi basically operational with minimal fuss.

A key detail is to edit the config.txt file on the root of SD card (found in /boot/config.txt once RPi is running) before inserting into the RPi; add this line to allow serial TTL communication and avoid needing to plug in a monitor and keyboard for initial setup:

enable_uart=1

Note that despite having 5V pins right next door, the Raspberry Pi serial port uses 3.3V logic.

Connect your favorite USB to TTL Serial cable:
Raspberry Pi pinout showing Serial TTL from raspberrypi.org docs
Then login with putty or some other terminal program. For more detailed information on setting up a headless Raspberry Pi, see this sparkfun how-to.

I prefer to run sudo raspi-config to do things like:
  • Assign password
Network Options:
  • assign host name such as "pi-hole"
Localisation Options:
  • Change the locale to en_US.UTF-8 UTF-8
  • Change timezone to Pacific Time
Interfacing Options:
  • Disable Camera
  • Enable SSH
  • Disable VNC
  • Disable SPI
  • Disable I2C
  • Enable Serial
  • Disable 1-Wire
  • Disable Remote GPIO
Advanced Options:
  • Expand Filesystem 
  • GPU Memory Split set to 16
Update raspi-config to the latest version.

Next assign a static IP address via sudo nano /etc/dhcpcd.conf and add these lines:

interface eth0
        static ip_address=192.168.1.77/24
        static routers=192.168.1.254
        static domain_name_servers=127.0.0.1

Put in your values for device IP address, router, and actual DNS (needed for initial install) . After setting up the pi_hole, set the DNS to 127.0.0.1 as shown.

Disable IPV6 unless you know you need it. Edit /etc/sysctl.conf and put these lines at the bottom:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.tun0.disable_ipv6 = 1


One of the main problems with the Raspberry Pi is the continual writing to the SD card and subsequent (lack of) reliability when in operation for years. See the log2ram install, below, that can help with this. Hackaday also has an article on the coolness of log2ram that refers to this log2ram blog by Erich Styger.

Next, main setup:

# system update
sudo apt-get update && sudo apt-get upgrade

# install essentials
sudo apt-get install git
sudo apt-get install fail2ban
sudo apt-get install dnsutils
sudo apt-get install arpwatch
sudo apt-get install iptables-persistent

# remove things that will not be used:
sudo apt-get purge realvnc-vnc-server --assume-yes

# basic pi-hole install
cd ~/
git clone --depth 1 https://github.com/pi-hole/pi-hole.git
cd "pi-hole/automated install/"
sudo bash basic-install.sh
sudo pihole -a -p

# log2ram install (optional)
cd ~/
curl -Lo log2ram.tar.gz https://github.com/azlux/log2ram/archive/master.tar.gz
tar xf log2ram.tar.gz
cd log2ram-master
chmod +x install.sh && sudo ./install.sh
# REBOOT BEFORE INSTALLING ANYTHING ELSE

This might be a good time to set that static domain_name_servers=127.0.0.1 setting.

Operational check for log2ram:

# not blank if working properly:
mount | grep log2ram

# not blank if working properly:
df -h | grep log2ram

If it appears the log files need more space, edit the /etc/log2ram.conf
.
See firewall notes for supported operating systems. Secure the RPi with IP Tables (optional):

# Flush the tables to apply changes
sudo iptables -F
sudo ip6tables -F

# Default policy to drop everything but our output to internet
sudo iptables -P FORWARD DROP
sudo iptables -P INPUT   DROP
sudo iptables -P OUTPUT  ACCEPT

# do the same for IPv6
sudo ip6tables -P FORWARD DROP
sudo ip6tables -P INPUT   DROP
sudo ip6tables -P OUTPUT  ACCEPT

# Allow established connections (the responses to our outgoing traffic)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow IPv6 established connections (the responses to our outgoing traffic)
sudo ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow local programs that use loopback (Unix sockets)
sudo iptables -A INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -j ACCEPT

# allow incoming SSH/SCP conections to this machine from 192.168.1.0/24 only
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -m state --state NEW -j ACCEPT

# In case a Windows drive is mapped, uncomment this line:
# sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 445 -m state --state NEW -j ACCEPT

# pi-hole ports
iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT
iptables -I INPUT 1 -p tcp -m tcp --dport 67 -j ACCEPT
iptables -I INPUT 1 -p udp -m udp --dport 67 -j ACCEPT
iptables -I INPUT 1 -p tcp -m tcp --dport 4711 -i lo -j ACCEPT

# save iptables to be in place after a reboot
sudo /sbin/iptables-save > ~/iptables.txt
sudo cp ~/iptables.txt /etc/iptables/rules
iptables-persistent
iptables --list


To make the IP Table changes stick, I chose iptables-persistent

See also: Linux Iptables: How to specify a range of IP addresses or ports.

If your pi-hole sits on a different network then all traffic it "sees" will appear to come from a single router IP address.

Some people may be interested in unbound recursive DNS server solution (see also this how-to). I didn't initially have much luck with it, and in fact I later saw my first system crash on a different Raspberry Pi within 24 hours of installing it.

Once everything is setup, there are MANY more lists to make the pi-hole even better. Thanks Jermal Smith for suggestions on other lists to block from his pi-hole blog.

For more information on manually adding domains, see the pihole command. Local lists can be appended by using the FILE:// syntax, although the data in that file does not seem to be successfully added to block list. No warning or other message is given:


file://c:/download/pi-hole/my_block_list.txt

Yet after refresh, the entry is not in the block domain list search:


So perhaps a GitHub gist is a better home for custom lists.

To add a large list of lists, such as this one from Jermal Smith, simply add them to the respective /etc/pihole/adlists.list on the pi-hole. Be sure to include only URL's and not the title text in the first line.

Some essentials that I needed to whitelist:


aka.ms - used for Visual Studio updates


A final fine-tuning: See the Raspberry Pi Power Requirements. It's a shame to waste standby power for things not being used. Note that the Raspberry Pi 3 Model B+ I chose typically uses 500mA. In contrast, the Raspberry Pi 2 uses only 350mA, Part of the difference is the on-board WiFi and Bluetooth capabilities.

These can be manually turned off:


sudo iwconfig wlan0 power off
This can be added to /etc/rc.local. Also consider editing /etc/modprobe.d/raspi-blacklist.conf as noted in the forum topic:


#wifi
blacklist brcmfmac
blacklist brcmutil
#bt
blacklist btbcm
blacklist hci_uart

or

# ref: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=138610
# bluetooth
blacklist hci_uart
blacklist btbcm
blacklist btintel
blacklist rfcom
blacklist btqca
blacklist btsdio
blacklist bluetooth


And edit the /boot/config.txt:


dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt


Note the 1000BaseT has a higher power requirement.

My Raspberry Pi operates at about 50°C; (specs qualified from -40°C to 85°C)

For more information, see the pi-hole discourse.

Sunday, April 6, 2014

I *finally* have RPi WiFi working (not easy with a hidden ssid)

woohoo!! ok, I've spent more time trying to get the WiFi working than anything else.

I tried everything... surely it is not difficult, considering how easy everything else was, no? No. The built-in WiFi configuration tool didn't not work for me. I found a cool WiFi tool called wicd. For more information see wifi on raspberry pi: a simple guide, at raspyfi.com (but it didn't work for my problem, either)

So the deal is: WiFi is easy to setup on RPi as long as the target AP has a ssid that is broadcasted. I prefer the security of an unbroadcasted ssid.  (details, details)

Google to the rescue! I found this awesome article on settig up the RPi as a WiFi radio. On the setup page, the author describes in detail how to setup WiFi with a hidden ssid.

We all know how over the years links change or simply go away, so I've copied the critical hidden ssid setup text from that article here (credit to Philip Burgess at adafruit):

Hidden Networks

If you run a hidden WiFi network — one that does not broadcast its SSID — this can still be made to work but is considerably more complicated. The slightest typo here, even one character, can prevent the system from joining the network! We strongly recommend using a “broadcast” network, it’s far easier and less error-prone.

sudo nano /etc/network/interfaces

Delete the {last} two lines {under "iface wlan0 inet dhcp" }   (wpa-ssid and wpa-psk) and replace with (indented):

pre-up wpa_supplicant -Dwext -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -B

sudo nano /etc/wpa_supplicant/wpa_supplicant.conf

ctrl_interface=/var/run/wpa_supplicant
update_config=1
ap_scan=2
eapol_version=1
network={
 ssid="my-network-ssid"
 scan_ssid=1
 mode=0
 proto=WPA2
 auth_alg=OPEN
 pairwise=CCMP
 group=CCMP
 key_mgmt=WPA-PSK
 psk="my-network-password"
}
Replace ssid and psk with your actual network name and password, in quotes.

Important: indent the 'network' section using tabs, not spaces.
In the end, my \\raspberrypi\c$\etc\network\interfaces file looks like this:
auto lo

iface lo inet loopback
iface eth0 inet dhcp

auto wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
  pre-up wpa_supplicant -Dwext -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf -B

And my \\raspberrypi\c$\etc\wpa_supplicant\wpa_supplicant.conf file looks like this (with my ssid and psk where noted):

ctrl_interface=/var/run/wpa_supplicant
update_config=1
ap_scan=2
eapol_version=1
network={
 ssid="myssid"
 scan_ssid=1
 mode=0
 proto=WPA2
 auth_alg=OPEN
 pairwise=CCMP
 group=CCMP
 key_mgmt=WPA-PSK
 psk="mypsk"
}

Find gojimmypi at gojimmypi.github.io

I'm currently working on my new blog home at  gojimmypi.github.io After implementing a variety of features such as dark mode , syntax hi...