====== Initial Setup Of A Raspberry Pi ====== ===== Prepare The SD card ===== ==== Copy The Raspbian image to the SD card ==== On a Linux system * Run the ''lsblk'' command before the SD card has been inserted to list all known block devices. * Insert the SD card into a card reader slot. * Run the ''lsblk'' command once more to see which block device has become available when the SD card was inserted. This can be e.g. ''/dev/sde'' or ''/dev/sdi'' or something else. In the command below, carefully replace ''/dev/sdX'' by the device node identified above. Be sure to use the right device node! **:!: Using the wrong device node may overwrite your computer's hard disk and thus damage your computer's operating system!** dd if=2017-11-29-raspbian-stretch.img of=/dev/sdX bs=8M conv=fsync The Raspbian image is not just small, so it may take some time until the ''dd'' command finishes. ==== Modifications Of The SD Card ==== After the Raspbian image has been copied to the SD card there are 2 partitions on the card that are accessible from your PC if you (re-)insert the SD card into your PC's card reader. === Enable SSH Access === For a ''headless'' operation of the Raspberry Pi, i.e. without keyboard and monitor connector, it is useful to enable SSH access right from the beginning. * Copy an empty text file ''ssh'' to the boot partition to enable ssh access The file is removed when the Pi boots, but the ''ssh'' service is enabled then. === Enable Wifi Access === If the Raspberry Pi has //only// a WIFI interface (e.g. the Raspberry Pi Zero W) then it may be useful to copy a file with SSID and authentication parameters for the WIFI network to the SD card, so the Pi can automatically connect to the WIFI network immediately after initial power-up. Create a text file ''wpa_supplicant.conf'' with a few lines similar to the example below: country=DE # omit if US ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid="wifi-ssid" psk="secret-wifi-password" key_mgmt=WPA-PSK } Set the ''country='', ''wifi-ssid'' and ''secret-wifi-password'' as appropriate for your country and network, and copy the file to the SD card's ''boot'' partition. When the Pi boots next time the file is moved to ''/etc/wpa_supplicant.conf'', and the Pi should be visible on the WIFI network with hostname **''raspberrypi''**. :!: There have been reports that **//this may not work as expected//** if the Pi has **//both//** a WIFI and an RJ45 network interface (e.g. the Raspberry Pi 3), so if an RJ45 connector is available then the WIFI interface should be configured later, when the Pi is running. If also [[#Enable SSH Access|ssh access has been enabled]] then the Pi [[#SSH Access|should be accessible via WIFI with ssh]] after power-up. ===== Change basic settings ===== ==== SSH Access ==== Immediately after initial power-up the Pi should visible on the network, either via WIFI, or via the cable network, with hostname **''raspberrypi''**, and can be accessed by command ''ssh pi@raspberrypi'', with default password ''raspberry''. Eventually, the user's ssh key should be copied to the target device to allow ssh access without password. On the local machine run: ssh-copy-id pi@raspberrypi Commands requiring root permissions have to be run with ''sudo''. At the first login as user ''pi'' the system should be upgraded to the current software version: sudo apt update sudo apt upgrade ==== Install etckeeper ==== **''etckeeper''** is a nice, optional tool used to track changes to the configuration files in ''/etc/'' then the best choice is to install it next, so the initial changes made afterwards can already be tracked in ''git''. First make sure ''git'' is installed: sudo apt install git # may already be installed Set a git user name and email address for user ''pi'' and user ''root'', but be sure to use the real hostname: git config --global user.name "pi" git config --global user.email "pi@`hostname`" sudo su - git config --global user.name "root" git config --global user.email "root@`hostname`" exit Then install ''etckeeper'', which automatically creates a git repo in ''/etc/'' and checks in the current config files: sudo apt install etckeeper Once this has been done, configuration changes in ''/etc/'' can easily be tracked. === Adding a remote repo for etckeeper === Like with other git repos it's possible to use a remote repos, e.g. for a backup. If the ''etckeeper'' git repo is to be pushed to a remote machine then the remote repo needs to be specified: sudo git remote add origin USER@HOSTNAME:REPONAME The remote repo has to exist when the current state is pushed the first time: sudo git push -u origin master If new commits are to be pushed //automatically// to the remote machine, the following line should be present in ''/etc/etckeeper/etckeeper.conf'': PUSH_REMOTE="origin" However, the drawback is that possibly local commits are pushed automatically while you're playing with configuration changes. ==== Raspi Configuration ==== sudo raspi-config should be run * ''Change User Password'' to change the password for user ''pi''. * ''Network Options'' to change the ''Hostname''. * ''Localisation Options'': * ''Change Timezone'', e.g. ''Europe'' --> ''Berlin'' for Germany. * ''Change Keyboard Layout'', e.g. ''Generic 105 (intl)'' --> ''German'' (accept defaults). * ''Change Locale'' select //additional// languages to be supported for the user interface, e.g. ''de_DE.UTF-8'' for Germany, and the default locale which should be ''en_GB.UTF-8'' or ''en_US.UTF-8''. * ''Change Wi-fi Country'' e.g. ''DE Germany'' for Germany unless this has already been done when [[#Enable Wifi Access|the SD card was prepared]]. When ''raspi-config'' is finished it asks to reboot now, and this should be done to let the changes come into effect. ==== Interfacing Options ==== It should be checked under ''Interfacing Options'' whether the serial port is to be used as a serial console or not, or whether the port and other interfaces are to be enabled or disabled. ===== Add specific bash alias commands ===== Create a new text file e.g. ''burnicki-aliases.sh'' in subdirectory ''/etc/profile.d/'' sudo nano /etc/profile.d/my-aliases.sh and add the required alias commands, e.g.: alias l="ls -lah" The file can have attributes ''644'', there's no need to make it executable. :!: Users have to re-login to have the specified alias(es) come into effect. ===== Create a specific user ===== Create user e.g. ''martin''. If the user should be allowed to use ''sudo'' then it should be added to the group ''sudoers''. If the user is also added to group ''staff'' then he can directly add own programs or scripts in ''/usr/local/bin'', without the need to use ''sudo'' for this. The advantage is that you can see which user has put a file into that directory, and ''/usr/local/bin/'' can even be turned into a git repo so changes can be done by any ''staff'' user and tracked normally sudo adduser martin sudo adduser martin sudo sudo adduser martin staff Please note that user ''pi'' is member of quite a few more different groups, e.g. \\ ''adm'' ''dialout'' ''cdrom'' ''audio'' ''video'' ''plugdev'' ''games'' ''users'' ''input'' ''netdev'' ''spi'' ''i2c'' ''gpio''\\ so possibly the new user might be added to these groups, too. Possibly you want to copy the user's public ssh key to the Pi to allow login without password. On the local machine run: ssh-copy-id martin@raspberrypi or use the hostname which has been specified before instead of ''raspberrypi''. ===== Enable sudo without password ===== Let the user be able to use ''sudo'' without entering a password, just like it's the defaut for user ''pi'': Change to directory ''/etc/sudoers.d''. There should be a file for user ''pi'', e.g. ''010_pi-nopasswd'' cd /etc/sudoers.d sudo cp 010_pi-nopasswd 011_martin-nopasswd # copy the existing file sudo chmod +w 011_martin-nopasswd # make the copied file writeable sudo nano 011_martin-nopasswd # edit the file to adjust the username sudo chmod -w 011_martin-nopasswd # Make the file readonly again'' After the change there should be 2 files with file attribute ''440'': -r--r----- 1 root root 27 Oct 18 2016 010_pi-nopasswd -r--r----- 1 root root 31 Jan 28 17:25 011_martin-nopasswd ===== Enable SSH Agent Forwarding ===== If **ssh agent forwarding** is enabled on the target machine then there's **no need to store a user's private SSH key** on the target machine, even if e.g. a remote git repo is to be accessed via ssh with the user's key. Instead, the user's private key only needs to be stored on the user's local machine from which the user first logs in to the target machine, e.g. the Raspberry Pi. On the target machine it's then possible to access e.g. a remote git repo via ssh, using the original user's name and credentials with the remote git repo. It's very helpful to have the **''keychain''** utility installed on the local machine which is the **only** location where the user's private key is stored. Edit the file ''/etc/ssh/ssh_config'', i.e., the ssh **client** configuration file: sudo nano /etc/ssh/ssh_config And edit or add the line ''ForwardAgent'' to read: ForwardAgent yes :!: Note: This enables agent forwarding for **all** hosts, which can be a security risk. It's better to enable this only for specific, trusted hosts. See: * [[http://www.unixwiz.net/techtips/ssh-agent-forwarding.html#fwd]] * [[https://www.veit-schiele.de/dienstleistungen/hosting/dokumentation/ssh-agent-forwarding]] ===== Postfix MTA ===== Normally there are some simple scripts that can be used to send email. However, if there is no network connection when the email is to be sent then the email may simply be dropped. If an MTA like ''postfix'' (or ''exim'') is used then such emails are queued and can be delivered later, when the network connection is available again, so no emails get lost. If emails are to be sent over the internet, and not just between nodes on the local network, then a ''smarthost'' should be configured, and real email addresses with valid domain names should be used. Otherwise emails might not be accepted by the recipient's email server. So install postfix and some related utilities: sudo apt install postfix bsd-mailx sasl2-bin It's important to install also ''sasl2-bin'' if a smarthost with authentication is to be used. ==== Automatic postfix configuration after apt install ==== General type of mail configuration: Satellite system The "mail name": raspi-martin (unchanged) SMTP relay host: (hostname of the smarthost) ==== Restrict to IPv4 addresses ==== If the machine hasn't been configured to support IPv6, or emails are to be sent globally but the internet connection doesn't support IPv6 then the postfix should be configured to use IPv4 interfaces only. Edit ''/etc/postfix/main.cf'' sudo nano /etc/postfix/main.cf Add the following line to configure usage of IPv4 interfaces only: # Use only IPv4 inet_protocols = ipv4 Possibly there is already a line reading ''inet_protocols = all'', which has to be commented out then. ==== Authentication with the smarthost ==== Edit ''/etc/postfix/main.cf'' sudo nano /etc/postfix/main.cf Add the following lines to enable sasl authentication: # Enable SASL authentication smtp_sasl_auth_enable = yes # Don't use 'noplaintext' below if passwords have to be sent as plain text smtp_sasl_security_options = noplaintext noanonymous # Specify the file that contains the credentials for the smarthost(s) smtp_sasl_password_maps = hash:/etc/postfix/sasl_password Create the file ''/etc/postfix/sasl_password'' with a text editor: sudo nano /etc/postfix/sasl_password and add the credentials required to log into the smarthost: smtp.netzmafia.de username:geheimespasswort Change the access permissions to ''600'' and run ''postmap'' to create an associated data base file: sudo chmod 600 /etc/postfix/sasl_password sudo postmap hash:/etc/postfix/sasl_password ==== Rewrite 'from' addresses to valid external email addresses ==== Edit ''/etc/postfix/main.cf'' sudo nano /etc/postfix/main.cf Add the following lines: # Specifiy the file that maps user names to valid email addresses sender_canonical_maps = hash:/etc/postfix/sender_canonical Create the file ''/etc/postfix/sender_canonical'' with a text editor: sudo nano /etc/postfix/sender_canonical Add one line for each user to be assigned a valid email address: pi pi@example.de root status@example.de martin martin.burnicki@burnicki.net Run ''postmap'' to create an associated data base file: sudo postmap hash:/etc/postfix/sender_canonical Don't forget to restart the postfix service after any configuration has been changed. ==== Sending a test email ==== The ''mailx'' program that has be installed above with ''postfix'' can be used to send a test email, e.g.: echo "Hello world" | mailx -s "Test email sent by `whoami`@`hostname`" martin.burnicki@meinberg.de ==== Troubleshooting postfix ===== * If an email couldn't be sent then it is held in a queue, and ''mailq'' can be run to show the queued emails. The output usually shows the reason why an email couldn't be delivered. Error and warning messages can also be found in the files ''/var/log/mail.err'' and ''/var/log/mail.warn''. * If there's an error saying ''SASL authentication failed; cannot authenticate to server ...: no mechanism available'' or ''No worthy mechs found'' then possibly a package providing SASL hasn't been installed, or the [[#Authentication with the smarthost|SASL authentication]] hasn't been configured correctly. The keyword ''noplaintext'' may have to be removed from the ''smtp_sasl_security_options'' in ''/etc/postfix/main.cf''. * The command ''postqueue -f'' can be used to retry sending queued emails immediately. * If an email could be sent correctly but doesn't reach the recipient then it may be queued or rejected by the smarthost / relay server. If the "from" address of such an email isn't valid then there's not even a bounce message returned to the sender. It may be helpful to inspect the mail queue on the smarthost, if possible. ==== Additional Configuration ===== FIXME To forward all email for local users to external email accounts, edit ''/etc/aliases/'' sudo nano /etc/aliases and add appropriate entries. For example there is already one entry that forwards all email for ''postmaster'' to ''root'', and we add another one that forwards all email for ''root'' to me: postmaster: root ## Added by martin: root: martin.burnicki@burnicki.net When finished, run sudo newaliases to let the changes come into effect. ==== Fixed 'From' Address with 'mailx' ==== If all email from an embedded device is to be sent using a standard ''From:'' header, e.g. From: raspberrypi and the **''mailx''** program is used to send emails, then a sender address with real name and valid email address can be added to the mailx configuration file: sudo nano /etc/mail.rc Add the line: set from='raspberrypi ' ---- --- //Martin Burnicki [[martin.burnicki@burnicki.net]] 2018-02-23//