Difference between revisions of "User:Mjb/FreeBSD on BeagleBone Black/Additional software"

From Offset
Jump to navigationJump to search
(Enable HTTPS service)
(Enable HTTPS service)
Line 211: Line 211:
 
         ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
 
         ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
 
         ssl_dhparam /etc/ssl/dhparams.pem;
 
         ssl_dhparam /etc/ssl/dhparams.pem;
        ssl_prefer_server_ciphers  on;
 
  
 
         add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;" always;
 
         add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;" always;

Revision as of 16:12, 27 October 2015

This is a continuation of my FreeBSD on BeagleBone Black notes. Any questions/comments, email me directly at root (at) skew.org.


Conveniences

Install nano

I prefer to use a 'visual' text editor with familiar command keys, multi-line cut & paste, and regex search & replace. I never got the hang of the classic editor vi, I find emacs too complicated, and ee is too limited. I used pico for many years, and now use nano, which is essentially a pico clone with more features.

Pretty much anytime I run portmaster to install or upgrade something, I actually run portmaster -D so it doesn't prompt me at the end about keeping the distfiles.
  • portmaster editors/nano

See my nano configuration files document for configuration info.

Install Perl libwww

I like to use the HEAD and GET commands from time to time, to diagnose HTTP problems. These are part of Perl's libwww module, which is installed by other ports like Spamassassin. Those commands are nice to have anyway, so I like to install them right away:

  • portmaster www/p5-libwww

This will install a bunch of other Perl modules as dependencies.

Build 'locate' database

Why wait for this to run on Sunday night? Do it now so the locate command will work:

  • /etc/periodic/weekly/310.locate

Replacement services

Install OpenNTPD

Instead of the stock ntpd, I prefer OpenNTPD because it's slightly easier to configure and will be safer to update. (I also was perhaps a bit overly paranoid about the stock ntpd's requirement of always listening to UDP port 123.)

  • portmaster net/openntpd
  • In /etc/rc.conf:
ntpd_enable="NO"
openntpd_enable="YES"
openntpd_flags="-s"

If you like, you can use /usr/local/etc/ntpd.conf as-is; it just says to use a random selection from pool.ntp.org, and to not listen on port 123 (it'll use random, temporary high-numbered ports instead).

Logging is same as for the stock ntpd.

  • service ntpd stop (obviously not necessary if you weren't running the stock ntpd before)
  • service openntpd start

You can tail the log to see what it's doing. You should see messages about valid and invalid peers, something like this:

ntp engine ready
set local clock to Mon Feb 17 11:44:06 MST 2014 (offset 0.002539s)
peer x.x.x.x now valid
adjusting local clock by -0.046633s

Because of the issues with Unbound needing accurate time before it can resolve anything, I am going to experiment with putting time.nist.gov's IP address in /etc/hosts as the local alias 'timenistgov':

timenistgov 128.138.141.172

...and then have that be the first server checked in /usr/local/etc/ntpd.conf:

server timenistgov
servers pool.ntp.org

The hope is that the IP address will suffice when DNS is failing!

Later, I can set up a script to try to keep the timenistgov entry in /etc/hosts up-to-date. Of course, this will not help if they ever change the IP address while the BBB is offline.

Install OpenSMTPD

The snapshots for the BBB come with the Sendmail daemon disabled in /etc/rc.conf, so immediately some emails (from root to root) start plugging up the queue, as you can see in /var/log/maillog.

This is what's in /etc/rc.conf:

sendmail_enable="NONE"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

Something interesting: from the messages in /var/log/maillog about missing /etc/mail/certs, it looks like the client supports STARTTLS without having to be custom-built with SASL2 like I had to do in FreeBSD 8. Not sure what's up with that.

Rather than enabling Sendmail, I am going to try OpenSMTPD now.

  • portmaster mail/opensmtpd – also installs various dependencies, including OpenSSL
  • echo smtpd_enable="YES" >> /etc/rc.conf
  • cp /usr/local/etc/mail/smtpd.conf.sample /usr/local/etc/mail/smtpd.conf

Edit smtpd.conf to your liking. You probably want the following, at the very least (and replace example.org with your domain, or comment out that line if you're not accepting mail from outside the BBB):

# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.

# To accept external mail, replace with: listen on all
listen on 127.0.0.1
listen on ::1

# If you edit the file, you have to run "smtpctl update table aliases"
table aliases file:/usr/local/etc/mail/aliases

# If 'from local' is omitted, it is assumed
accept from any for domain "example.org" alias <aliases> deliver to mbox
accept for local alias <aliases> deliver to mbox
accept for any relay

Then start the service:

  • service smtpd start

OpenSMTPD problems

The service first runs smtpd -n to do a sanity check on the smtpd.conf file. I noticed two problems with this:

1. If hostname returns a non-FQDN which is not resolvable (e.g. the default, "beaglebone", and this name is not mentioned in /etc/hosts), then smtpd may fail at first with a strange error message:

Performing sanity check on smtpd configuration:
invalid hostname: getaddrinfo() failed: hostname nor servname provided, or not known
/usr/local/etc/rc.d/smtpd: WARNING: failed precmd routine for smtpd

To work around this, make sure the result of running hostname is a FQDN like "beaglebone.example.org.", which requires modifying the hostname line in /etc/rc.conf, or just add the unqualified hostname as another alias for localhost in /etc/hosts, which is a good idea to do anyway.

2. smtpd consumes all available memory for over 20 minutes if I leave the table aliases line in the config. It eventually works, but not until after other essential services have failed due to the memory churn.

On 2015-10-19 I posted to the misc@opensmtpd.org list about both issues.

3. smtpd has more memory problems when called on to actually deliver mail, as happens when daily maintenance scripts run at night. I get numerous "swap_pager_getswapspace(16): failed" messages interspersed with "pid 41060 (smtpctl), uid 0, was killed: out of swap space".

Install MySQL

  • portmaster databases/mysql56-server

This will install mysql56-client, cmake, perl, and libedit. cmake has many dependencies, including Python (py-sphinx), curl, expat, jsoncpp, and libarchive. Depending on whether you've got Perl and Python already (and up-to-date), this will take roughly 3 to 6 hours.

MySQL is a bit of a RAM hog. On a lightly loaded system, it should do OK, though. Just make sure you have swap space!

Secure and start it

Ensure the server won't be accessible to the outside world, enable it, and start it up:

  • echo '[mysqld]\nbind-address=127.0.0.1' > /var/db/mysql/my.cnf
  • echo 'mysql_enable="YES"' >> /etc/rc.conf
  • service mysql-server start – this may take a minute, as it will have to use a little bit of swap.

If you are not restoring data from a backup (see next subsection), do the following to delete the test databases and set the passwords (yes, plural!) for the root account:

  • Refer to Securing the Initial MySQL Accounts.
  • mysql -uroot
    • DELETE FROM mysql.db WHERE Db='test';
    • DELETE FROM mysql.db WHERE Db='test\_%';
    • SET PASSWORD FOR 'root'@'localhost' = PASSWORD('foo'); – change foo to the actual password you want
    • SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('foo'); – use the same password
    • SET PASSWORD FOR 'root'@'::1' = PASSWORD('foo'); – use the same password
    • SELECT User, Host, Password FROM mysql.user WHERE user='root'; – see what other hosts have an empty root password, and either set a password or delete those rows. For example: DELETE FROM mysql.user WHERE Host='localhost.localdomain';
    • \q
  • mysqladmin -uroot -pfoo – This is to make sure the password works and mysqld is alive.

(If you were to just do mysqladmin password foo, it would only set the password for 'root'@'localhost'.)

Restore data from backup

On my other server, every day, I run a script to create a backup of my MySQL databases. I can copy the resulting .sql file (bzip2'd), which can be piped right into the client on this machine to populate the database here:

  • bzcat mysql-backup-20151022.sql.bz2 | mysql -uroot -pfoofoo is the root password, of course

The backed up data includes the mysql.db and mysql.user tables, thus includes all databases and account & password data from the other server. Obviously there is some risk if the other server has insecure accounts and test databases.

After loading from backup, I recommend also performing any housekeeping needed to ensure the tables are compatible with this server:

  • mysql_upgrade -pfoo --force

Install nginx

I'm a longtime Apache httpd administrator (even co-ran apache.org for a while) but am going to see if nginx will work just as well for what I need:

  • HTTPS with SNI (virtual host) and HSTS header support
  • URL rewriting and aliasing
  • PHP (to support MediaWiki)
  • basic authentication
  • server-parsed HTML (for timestamp comments, syntax coloring)
  • fancy directory indexes (custom comments, but I can live without)

Let's get started:

  • portmaster -D www/nginx – installs PCRE as well
    • Modules I left enabled: IPV6, HTTP, HTTP_CACHE, HTTP_REWRITE, HTTP_SSL, HTTP_STATUS, WWW
    • Modules I also enabled: HTTP_FANCYINDEX
  • echo 'nginx_enable="YES"' >> /etc/rc.conf

Try it out:

  • service nginx start
  • Visit your IP address in a browser (just via regular HTTP). You should get a "Welcome to nginx!" page.

Immediately I'm struck by how lightweight it is: processes under 14 MB instead of Apache's ~90 MB.

Enable HTTPS service

Prep for HTTPS support (if you haven't already done this):

  • Put your private key (.key) and cert (.crt or .pem) somewhere.
  • Create a 2048-bit Diffie-Hellman group: openssl dhparam -out /etc/ssl/dhparams.pem 2048

Enable HTTPS support by putting this in /usr/local/etc/nginx/nginx.conf for each HTTPS server:

    # HTTPS server
    #
    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      /path/to/your/cert;
        ssl_certificate_key  /path/to/your/server_key;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
        ssl_dhparam /etc/ssl/dhparams.pem;

        add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;" always;

        location / {
            root   /usr/local/www/nginx;
            index  index.html index.htm;
        }
    }

This config includes HSTS support, BEAST attack mitigation, and Perfect" forward secrecy (PFS).

  • service nginx reload
  • Check the site again, but this time via HTTPS. Once you verify it's working, you can tweak the config as you like.

Install PHP

  • portmaster lang/php56

For use via nginx, make sure the FPM option is checked (it is by default). FPM is a FastCGI Process Manager. It runs a server on localhost port 9000 which handles, via a binary protocol, the launching of PHP processes as if they were CGI scripts.

Configure nginx to use PHP FPM

  • echo 'php_fpm_enable="YES"' >> /etc/rc.conf
  • service php-fpm start

Add to /usr/local/etc/nginx/nginx.conf:

        location ~ [^/]\.php(/|$) {
            root /usr/local/www/nginx;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            fastcgi_split_path_info ^(.+?\.php)(/.*)$;
            if (!-f $document_root$fastcgi_script_name) {
                return 404;
            }
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            include        fastcgi_params;
        }
  • service nginx reload
  • echo '<?php var_export($_SERVER)?>' > /usr/local/www/nginx/test.php
  • echo '<?php echo phpinfo(); ?>' > /usr/local/www/nginx/phpinfo.php
  • In your browser, visit /test.php/foo/bar.php?v=1 and /phpinfo.php ... when confirmed working, move the test files to somewhere not publicly accessible.

Distributed computing projects

This is a tale of failure. None of the projects supported by BOINC have native support for armv6 processors. This includes my longtime favorite, distributed.net. So it's not an option to run these on the BeagleBone Black right now.

Nevertheless, here are the notes I started taking when I tried to get something working:

I like to run the distributed.net client on all my machines, but it is not open-source, and there are no builds for ARMv6 on FreeBSD yet.

Ordinarily you can run the client through BOINC with the Moo! Wrapper, but this doesn't work either. Here's the general idea with BOINC, though:

Install BOINC and start the client:

  • portmaster net/boinc – this will install several dependencies, including Perl. In the 'make config' screens for those, I generally disable docs & examples, X11, NLS (for now), and IPv6 (for now). When installing Perl, I chose to disable 64bit_int because it says "on i386".
  • echo boinc_client_enable="YES" >> /etc/rc.conf
  • service boinc-client start — there's a bug in the port; it writes the wrong pid to the pidfile, so subsequent 'service' commands will fail
  • Create account on the BOINC project page you're interested in
  • Go to your account info on that page and click on Account Keys
  • Create ~boinc/account_whatever.xml as instructed. Put the account key (not weak key) in a file, e.g. ~boinc/whatever.key.
  • boinccmd --project_attach http://moowrap.net/ `cat ~boinc/whatever.key`
  • tail -f ~boinc/stdoutdae.txt — this is the log

Blast! Look what comes up in the log: This project doesn't support computers of type armv6-pc-freebsd

None of the projects I tried (Moo!, SETI@Home, Enigma@Home) are supported. So I went ahead and commented out the boinc_client_enable line in /etc/rc.conf and manually killed the boinc-client process.

I later filed a freebsd-armv6 client port request at distributed.net.