<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Danschmid</title>
    <link>https://danschmid.writeas.com/</link>
    <description>A Novel about my FreeBSD journey</description>
    <pubDate>Mon, 13 Apr 2026 14:08:41 +0000</pubDate>
    <image>
      <url>https://i.snap.as/fBgsimOC.png</url>
      <title>Danschmid</title>
      <link>https://danschmid.writeas.com/</link>
    </image>
    <item>
      <title>Install Vaultwarden Password Server on FreeBSD</title>
      <link>https://danschmid.writeas.com/install-vaultwarden-password-server-on-freebsd?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In this guide, I explain how to install and set up Vaultwarden on FreeBSD.&#xA;&#xA;!--more--&#xA;&#xA;What is Vaultwarden&#xA;&#xA;Vaultwarden is an alternative implementation of the Bitwarden server API, written in Rust and compatible with upstream Bitwarden clients. It is perfect for self-hosted use when using the official, resource-intensive service is not ideal.&#xA;&#xA;We can install it as follows:&#xA;&#xA;$: pkg install vaultwarden&#xA;&#xA;Then we copy the sample configuration:&#xA;&#xA;$: cp /usr/local/etc/rc.conf.d/vaultwarden.sample /usr/local/etc/rc.conf.d/vaultwarden&#xA;&#xA;However, before we change our Vaultwarden configuration, we need an admin token, which we can create with the following command:&#xA;&#xA;$: openssl rand -base64 48&#xA;&#xA;We now copy the created token and change the configuration.&#xA;&#xA;Note: If we want to use the web interface, we have to set SIGNUPSALLOWED to true. Under ADMINTOKEN we paste our copied token.&#xA;Furthermore, we can change our email server configuration here.&#xA;&#xA;$: nano /usr/local/etc/rc.conf.d/vaultwarden =  ROCKETADDRESS=127.0.0.1&#xA;export ROCKETADDRESS&#xA;&#xA;ROCKETPORT=4567 # your port here&#xA;export ROCKETPORT&#xA;&#xA;ROCKETTLS=&#39;{certs = &#34;/ssl/fullchain.pem&#34;, key = &#34;/ssl/key.pem&#34;}&#39;&#xA;LOGFILE=&#39;/data/bitwarden.log&#39;&#xA;&#xA;SIGNUPSALLOWED=&#39;true&#39;&#xA;export SIGNUPSALLOWED&#xA;&#xA;DOMAIN=&#39;https://vaultwarden.domain&#39;&#xA;export DOMAIN&#xA;&#xA;ADMINTOKEN= # generate one with ~$ openssl rand -base64 48&#xA;export ADMINTOKEN&#xA;&#xA;SMTPHOST=localhost&#xA;export SMTPHOST&#xA;&#xA;SMTPFROM=noreply@localhost&#xA;export SMTPFROM&#xA;&#xA;SMTPPORT=25&#xA;export SMTPPORT&#xA;&#xA;SMTPSSL=false&#xA;export SMTPSSL&#xA;&#xA;SMTPUSERNAME=&#xA;export SMTPUSERNAME&#xA;&#xA;SMTPPASSWORD=&#xA;export SMTPPASSWORD&#xA;&#xA;Now that we have changed our configuration, we can enable the Vaultwarden service and start it for the first time.&#xA;&#xA;$: service vaultwarden enable&#xA;$: service vaultwarden start&#xA;$: service vaultwarden status&#xA;&#xA;To be able to use the web interface, we will use Nginx as a reverse proxy. To complete this, we first create the Nginx configuration:&#xA;&#xA;$: nano /usr/local/etc/nginx/vhosts/vaultwarden.conf =  server {&#xA;&#x9;listen 80;&#xA;&#xA;    servername vaultwarden.domain;&#xA;&#xA;    # Allow large attachments&#xA;    clientmaxbodysize 128M;&#xA;&#xA;    location / {&#xA;        proxypass http://127.0.0.1:4567;&#xA;        proxysetheader Host $host;&#xA;        proxysetheader X-Real-IP $remoteaddr;&#xA;        proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;        proxysetheader X-Forwarded-Proto $scheme;&#xA;    }&#xA;&#xA;    location /notifications/hub {&#xA;        proxypass http://127.0.0.1:3012;&#xA;        proxysetheader Upgrade $httpupgrade;&#xA;        proxysetheader Connection &#34;upgrade&#34;;&#xA;    }&#xA;&#xA;    location /notifications/hub/negotiate {&#xA;       proxy_pass http://127.0.0.1:4567;&#xA;    }&#xA;}&#xA;&#xA;We need another entry in our host&#39;s file:&#xA;&#xA;$: nano /etc/hosts =  127.0.0.1 vaultwarden.domain&#xA;&#xA;Since it&#39;s more secure to deploy Vaultwarden over HTTPS, and we still need let&#39;s-encrypt certificates for that, we simply run the “certbot”&#xA;command in our terminal and let it automatically create a certificate for our new domain.&#xA;&#xA;Finally, we restart the Nginx once.&#xA;&#xA;$: service nginx restart&#xA;&#xA;Now we can open our freshly installed Vaultwarden service via the web browser.&#xA;&#xA;Here, we can create a new user and manage our passwords securely in the future.&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/install-vaultwarden-password-server-on-freebsd&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>In this guide, I explain how to install and set up Vaultwarden on FreeBSD.</p>



<h2 id="what-is-vaultwarden" id="what-is-vaultwarden">What is Vaultwarden</h2>

<p><a href="https://freshports.org/security/vaultwarden" rel="nofollow">Vaultwarden</a> is an alternative implementation of the Bitwarden server API, written in Rust and compatible with upstream Bitwarden clients. It is perfect for self-hosted use when using the official, resource-intensive service is not ideal.</p>

<p>We can install it as follows:</p>

<pre><code class="language-bash">$: pkg install vaultwarden
</code></pre>

<p>Then we copy the sample configuration:</p>

<pre><code class="language-bash">$: cp /usr/local/etc/rc.conf.d/vaultwarden.sample /usr/local/etc/rc.conf.d/vaultwarden
</code></pre>

<p>However, before we change our Vaultwarden configuration, we need an admin token, which we can create with the following command:</p>

<pre><code class="language-bash">$: openssl rand -base64 48
</code></pre>

<p>We now copy the created token and change the configuration.</p>

<p><strong>Note:</strong> If we want to use the web interface, we have to set SIGNUPS<em>ALLOWED to true. Under ADMIN</em>TOKEN we paste our copied token.
Furthermore, we can change our email server configuration here.</p>

<pre><code class="language-bash">$: nano /usr/local/etc/rc.conf.d/vaultwarden =&gt;

ROCKET_ADDRESS=127.0.0.1
export ROCKET_ADDRESS

ROCKET_PORT=4567 # your port here
export ROCKET_PORT

# ROCKET_TLS=&#39;{certs = &#34;/ssl/fullchain.pem&#34;, key = &#34;/ssl/key.pem&#34;}&#39;
# LOG_FILE=&#39;/data/bitwarden.log&#39;

SIGNUPS_ALLOWED=&#39;true&#39;
export SIGNUPS_ALLOWED

DOMAIN=&#39;https://vaultwarden.domain&#39;
export DOMAIN

ADMIN_TOKEN= # generate one with ~$ openssl rand -base64 48
export ADMIN_TOKEN

SMTP_HOST=localhost
export SMTP_HOST

SMTP_FROM=noreply@localhost
export SMTP_FROM

SMTP_PORT=25
export SMTP_PORT

SMTP_SSL=false
export SMTP_SSL

# SMTP_USERNAME=
# export SMTP_USERNAME

# SMTP_PASSWORD=
# export SMTP_PASSWORD
</code></pre>

<p>Now that we have changed our configuration, we can enable the Vaultwarden service and start it for the first time.</p>

<pre><code class="language-bash">$: service vaultwarden enable
$: service vaultwarden start
$: service vaultwarden status
</code></pre>

<p>To be able to use the web interface, we will use Nginx as a reverse proxy. To complete this, we first create the Nginx configuration:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/nginx/vhosts/vaultwarden.conf =&gt;

server {
	listen 80;

    server_name vaultwarden.domain;

    # Allow large attachments
    client_max_body_size 128M;

    location / {
        proxy_pass http://127.0.0.1:4567;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /notifications/hub {
        proxy_pass http://127.0.0.1:3012;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &#34;upgrade&#34;;
    }

    location /notifications/hub/negotiate {
       proxy_pass http://127.0.0.1:4567;
    }
}
</code></pre>

<p>We need another entry in our host&#39;s file:</p>

<pre><code class="language-bash">$: nano /etc/hosts =&gt;

127.0.0.1 vaultwarden.domain
</code></pre>

<p>Since it&#39;s more secure to deploy Vaultwarden over HTTPS, and we still need let&#39;s-encrypt certificates for that, we simply run the “certbot”
command in our terminal and let it automatically create a certificate for our new domain.</p>

<p>Finally, we restart the Nginx once.</p>

<pre><code class="language-bash">$: service nginx restart
</code></pre>

<p>Now we can open our freshly installed Vaultwarden service via the web browser.</p>

<p><img src="https://i.snap.as/1Acs8RC8.png" alt=""/></p>

<p>Here, we can create a new user and manage our passwords securely in the future.</p>

<p><a href="https://remark.as/p/danschmid/install-vaultwarden-password-server-on-freebsd" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/install-vaultwarden-password-server-on-freebsd</guid>
      <pubDate>Sun, 18 Sep 2022 07:51:58 +0000</pubDate>
    </item>
    <item>
      <title>Install Navidrome Music Server on FreeBSD</title>
      <link>https://danschmid.writeas.com/install-navidrome-music-server-on-freebsd?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In this tutorial, I explain how to install the Navidrome music server on FreeBSD.&#xA;&#xA;!--more--&#xA;&#xA;What is Navidrome?&#xA;&#xA;Navidrome is an open-source web-based music collection server and streamer. It gives us the freedom to listen to our music collection from any browser&#xA;or mobile device. It&#39;s like our own personal Spotify!&#xA;&#xA;Furthermore, it offers the following feature:&#xA;&#xA;Manages huge music collections&#xA;Streams virtually any audio format available&#xA;Reads and uses all of our beautifully curated metadata&#xA;Great support for compilations (various artists&#39; albums) and box sets (multi-disc albums)&#xA;Multi-user, each user has their playlists, favorites, etc.&#xA;Very low resource consumption&#xA;Automatically monitors your library for changes, imports new files, and reloads new metadata&#xA;Modern and responsive web interface based on Material UI&#xA;Compatible with all Subsonic/Madsonic/Airsonic clients&#xA;Transcoding on the fly. It can be set per user/player. Opus encoding is supported.&#xA;&#xA;How can we install it?&#xA;&#xA;Installation is simple, we just need to run the following command:&#xA;&#xA;$: pkg install navidrome&#xA;&#xA;After the installation is through, we can then edit the corresponding configuration file.&#xA;&#xA;$: nano /usr/local/etc/navidrome/config.toml&#xA;&#xA;You can have a look at it. You will find a lot of configuration options.  What is important is that you set the path to your music collection correctly.&#xA;&#xA;If you have configured the whole thing according to your wishes, we still have to activate the RC service and then start it once.&#xA;&#xA;$: servive navidrome enable&#xA;$: servive navidrome start&#xA;&#xA;Nginx configuration&#xA;&#xA;We use Nginx as a reverse proxy server. Likewise, we now create the following file under /usr/local/etc/nginx/vhosts:&#xA;&#xA;$: nano /usr/local/etc/nginx/vhosts/navidrome.conf  ⇒&#xA;&#xA;server {&#xA;    servername navidrome.domain;&#xA;&#xA;    location / {&#xA;        proxypass http://127.0.0.1:4533;&#xA;        proxyhttpversion 1.1;&#xA;        proxycachebypass $httpupgrade;&#xA;&#xA;        # proxy headers&#xA;        proxysetheader Upgrade $httpupgrade;&#xA;        proxysetheader Connection &#34;upgrade&#34;;&#xA;        proxysetheader Host $host;&#xA;        proxysetheader X-Real-IP $remoteaddr;&#xA;        proxysetheader X-Forwarded-For $proxyaddxforwardedfor;&#xA;        proxysetheader X-Forwarded-Proto $scheme;&#xA;        proxysetheader X-Forwarded-Host $host;&#xA;        proxysetheader X-forwarded-port $serverport;&#xA;&#xA;        # proxy timeouts&#xA;        proxyconnecttimeout 60s;&#xA;        proxysendtimeout 60s;&#xA;        proxyreadtimeout 60s;&#xA;    }&#xA;}&#xA;&#xA;In our /etc/hosts, we add the following line.&#xA;&#xA;$: nano /etc/rc.conf ⇒&#xA;&#xA;127.0.0.1 navidrome.domain&#xA;&#xA;Then we restart the Nginx.&#xA;&#xA;$: service nginx restart&#xA;&#xA;We can now open Navidrome via the web browser.&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/install-navidrome-music-server-on-freebsd&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>In this tutorial, I explain how to install the Navidrome music server on FreeBSD.</p>



<h2 id="what-is-navidrome" id="what-is-navidrome">What is Navidrome?</h2>

<p>Navidrome is an open-source web-based music collection server and streamer. It gives us the freedom to listen to our music collection from any browser
or mobile device. It&#39;s like our own personal Spotify!</p>

<p>Furthermore, it offers the following feature:</p>
<ul><li>Manages huge music collections</li>
<li>Streams virtually any audio format available</li>
<li>Reads and uses all of our beautifully curated metadata</li>
<li>Great support for compilations (various artists&#39; albums) and box sets (multi-disc albums)</li>
<li>Multi-user, each user has their playlists, favorites, etc.</li>
<li>Very low resource consumption</li>
<li>Automatically monitors your library for changes, imports new files, and reloads new metadata</li>
<li>Modern and responsive web interface based on Material UI</li>
<li>Compatible with all Subsonic/Madsonic/Airsonic clients</li>
<li>Transcoding on the fly. It can be set per user/player. Opus encoding is supported.</li></ul>

<h2 id="how-can-we-install-it" id="how-can-we-install-it">How can we install it?</h2>

<p>Installation is simple, we just need to run the following command:</p>

<pre><code class="language-bash">$: pkg install navidrome
</code></pre>

<p>After the installation is through, we can then edit the corresponding configuration file.</p>

<pre><code class="language-bash">$: nano /usr/local/etc/navidrome/config.toml
</code></pre>

<p>You can have a look at it. You will find a lot of configuration options.  What is important is that you set the path to your music collection correctly.</p>

<p>If you have configured the whole thing according to your wishes, we still have to activate the RC service and then start it once.</p>

<pre><code class="language-bash">$: servive navidrome enable
$: servive navidrome start
</code></pre>

<h2 id="nginx-configuration" id="nginx-configuration">Nginx configuration</h2>

<p>We use Nginx as a reverse proxy server. Likewise, we now create the following file under /usr/local/etc/nginx/vhosts:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/nginx/vhosts/navidrome.conf  ⇒

server {
    server_name navidrome.domain;

    location / {
        proxy_pass http://127.0.0.1:4533;
        proxy_http_version 1.1;
        proxy_cache_bypass $http_upgrade;

        # proxy headers
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection &#34;upgrade&#34;;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-forwarded-port $server_port;

        # proxy timeouts
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}
</code></pre>

<p>In our /etc/hosts, we add the following line.</p>

<pre><code class="language-bash">$: nano /etc/rc.conf ⇒

127.0.0.1 navidrome.domain
</code></pre>

<p>Then we restart the Nginx.</p>

<pre><code class="language-bash">$: service nginx restart
</code></pre>

<p>We can now open Navidrome via the web browser.</p>

<p><img src="https://i.snap.as/StcgRdbs.png" alt=""/></p>

<p><a href="https://remark.as/p/danschmid/install-navidrome-music-server-on-freebsd" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/install-navidrome-music-server-on-freebsd</guid>
      <pubDate>Sun, 18 Sep 2022 07:46:34 +0000</pubDate>
    </item>
    <item>
      <title>Install Airsonic on FreeBSD</title>
      <link>https://danschmid.writeas.com/install-airsonic-on-freebsd?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In this tutorial, I&#39;ll explain how to install Airsonic on FreeBSD.&#xA;&#xA;!--more--&#xA;&#xA;What is Airsonic?&#xA;&#xA;It&#39;s a free, web-based media streamer that provides ubiquitous access to our music. Airsonic was developed for huge music collections. Although it&#39;s optimized for MP3 streaming, it works for any audio or video format that can be streamed over HTTP, such as. B. AAC and OGG. Using transcoder plug-ins, Airsonic supports direct conversion and streaming of virtually all audio formats including WMA, FLAC, APE, Musepack, WavPack and Shorten.&#xA;&#xA;Installation&#xA;&#xA;We first install wget, openjdk11 and ffmpeg with the following command:&#xA;&#xA;$: pkg install wget openjdk11 ffmpeg&#xA;&#xA;Next, we create the required directories with the next commands and change them to the directory /usr/local/airsonic:&#xA;&#xA;$: mkdir /var/airsonic/&#xA;&#xA;$: mkdir /usr/local/airsonic&#xA;&#xA;$: cd /usr/local/airsonic&#xA;&#xA;Now we can download Airsonic from their GitHub site with wget.&#xA;&#xA;$: wget https://github.com/airsonic/airsonic/releases/download/v10.6.2/airsonic.war&#xA;&#xA;Note: We can find the latest version here. Meanwhile, there is also a fork called Airsonic Advanced, which is a more modern implementation of Airsonic. More information can be found here.&#xA;&#xA;Then we have to set a system link so that Airsonic can find the FFmpeg transcoder.&#xA;&#xA;$: ln -s /usr/local/bin/ffmpeg /var/airsonic/transcode/ffmpeg&#xA;&#xA;We can now start Airsonic on a test basis via the command line.&#xA;&#xA;$: /usr/local/bin/java -jar /usr/local/airsonic/airsonic.war&#xA;&#xA;Create a FreeBSD RC script&#xA;&#xA;Next, we want to create an rc.d script for Airsonic.&#xA;&#xA;$: nano /etc/rc.d/airsonic =  #!/bin/sh&#xA;#&#xA;$FreeBSD: airsonic $&#xA;&#xA;PROVIDE: airsonic REQUIRE: LOGIN KEYWORD: shutdown&#xA;&#xA;Configuration settings for airsonic in /etc/rc.conf:&#xA;&#xA;airsonicenable (bool):&#xA;Set to &#34;NO&#34; by default. Set it to &#34;YES&#34; to enable airsonic.&#xA;&#xA;airsonichome (str):&#xA;Set to &#34;/var/airsonic&#34; by default.&#xA;&#xA;airsonichost (str):&#xA;Set to &#34;0.0.0.0&#34; by default. Specify which IP address to listen to.&#xA;&#xA;airsonicport (int):&#xA;Set to &#34;4040&#34; by default. Specify which port to listen on for HTTP(S).&#xA;&#xA;airsoniccontextpath (str):&#xA;Set to &#34;/&#34; by default. Specify the last part of the airsonic URL, typically &#34;/&#34; or &#34;/airsonic&#34;.&#xA;&#xA;airsonicinitmemory (int):&#xA;Set to &#34;192&#34; by default. Specify the memory initial size (Java heap size) in megabytes.&#xA;&#xA;airsonicmaxmemory (int):&#xA;Set to &#34;384&#34; by default. Specify the memory limit (Java heap size) in megabytes.&#xA;&#xA;. /etc/rc.subr&#xA;&#xA;export LANG=enEN.UTF-8&#xA;&#xA;name=airsonic&#xA;&#xA;desc=&#34;Airsonic is a free, web-based media streamer, providing ubiquitous access to your music&#34;&#xA;&#xA;rcvar=${name}enable&#xA;&#xA;pidfile=&#34;/var/run/${name}.pid&#34;&#xA;&#xA;loadrcconfig &#34;${name}&#34;&#xA;&#xA;: ${airsonicenable:=&#34;NO&#34;}&#xA;: ${airsonicuser:=&#34;root&#34;} #: ${airsonicuser:=&#34;media&#34;}&#xA;: ${airsonicgroup:=&#34;wheel&#34;} #: ${airsonicgroup:=&#34;media&#34;}&#xA;: ${airsonichome:=&#34;/var/airsonic&#34;}&#xA;: ${airsonicaddress:=&#34;0.0.0.0&#34;}&#xA;: ${airsonicport:=&#34;8080&#34;}&#xA;: ${airsonicssl:=&#34;NO&#34;}&#xA;: ${airsoniccontextpath:=&#34;/&#34;}&#xA;: ${airsonicinitmemory:=&#34;1024&#34;}&#xA;: ${airsonicmaxmemory:=&#34;2048&#34;}&#xA;: ${airsonicchdir:=&#34;/usr/local/airsonic&#34;}&#xA;&#xA;startcmd=airsonicstart&#xA;stopcmd=airsonicstop&#xA;restartcmd=airsonicrestart&#xA;statuscmd=airsonicstatus&#xA;startprecmd=&#34;export LCCTYPE=&#39;enUS.UTF-8&#39;&#34;&#xA;&#xA;-Dairsonic.defaultMusicFolder=${airsonichome}/artists &#xA;-Dairsonic.defaultUploadFolder=${airsonichome}/incoming &#xA;-Dairsonic.defaultPodcastFolder=${airsonichome}/podcasts &#xA;-Dairsonic.defaultPlaylistImportFolder=${airsonichome}/playlists/import &#xA;-Dairsonic.defaultPlaylistExportFolder=${airsonichome}/playlists/export &#xA;-Dairsonic.defaultPlaylistBackupFolder=${airsonichome}/playlists/backup \&#xA;&#xA;command=&#34;/usr/sbin/daemon -p ${pidfile} -f -u ${airsonicuser}&#34;&#xA;&#xA;procname=&#34;/usr/local/bin/java&#34;&#xA;&#xA;commandargs=&#34;-Dairsonic.home=${airsonichome} -Dserver.address=${airsonicaddress} -Dserver.port=${airsonicport} -Dserver.context-path=${airsoniccontextpath} -Xms${airsonicinitmemory}m -Xmx${airsonicmaxmemory}m -Djava.awt.headless=true -jar ${airsonicchdir}/airsonic.war&#34;&#xA;&#xA;commandargs1=&#34;-Dairsonic.home=${airsonichome} -Dserver.port=${airsonicport} -jar ${airsonicchdir}/airsonic.war&#34;&#xA;&#xA;airsonicstart() {&#xA;echo &#34;Starting Airsonic&#34;&#xA;echo &#34;${command} ${procname} ${commandargs}&#34;&#xA;cd ${airsonicchdir}&#xA;${command} ${procname} ${commandargs}&#xA;}&#xA;&#xA;airsonicstop() {&#xA;echo &#34;Stopping Airsonic&#34;&#xA;kill cat ${pidfile}&#xA;rm ${pidfile}&#xA;}&#xA;&#xA;airsonicrestart() {&#xA;airsonicstop&#xA;sleep 1&#xA;airsonicstart&#xA;}&#xA;&#xA;airsonicstatus() {&#xA;if airsoniccheck; then&#xA;echo &#34;Airsonic running&#34;&#xA;return 1&#xA;else&#xA;echo &#34;Airsonic not running&#34;&#xA;return 0&#xA;fi&#xA;}&#xA;&#xA;airsoniccheck() {&#xA;if [ -f ${pidfile} ]; then&#xA;return 0&#xA;else&#xA;return 1&#xA;fi&#xA;}&#xA;&#xA;runrccommand &#34;$1&#34;&#xA;&#xA;We then have to make the script executable.&#xA;&#xA;$: chmod +x /etc/rc.d/airsonic&#xA;&#xA;We will now activate and start Airsonic.&#xA;&#xA;$: service airsonic enable&#xA;$: service airsonic start&#xA;&#xA;NGINX configuration&#xA;&#xA;We use NGINX as the reverse proxy server. Likewise, we now create the following file under /usr/local/etc/nginx/vhosts:&#xA;&#xA;$: nano /usr/local/etc/nginx/vhosts/airsonic.conf =  server {&#xA;    listen 80;&#xA;    servername music.&lt;domain  ;&#xA;&#xA;    # Proxy to the Airsonic server&#xA;    location / {&#xA;        proxypass &#x9;&#x9;&#x9;&#x9;&#x9;&#x9;&#x9;http://127.0.0.1:8080;&#xA;        proxyhttpversion                 1.1;&#xA;&#x9;&#x9;    proxycachebypass                 $httpupgrade;&#xA;&#xA;&#x9;      # Proxy headers&#xA;&#x9;&#x9;    proxysetheader Upgrade           $httpupgrade;&#xA;&#x9;&#x9;    proxysetheader Connection        &#34;upgrade&#34;;&#xA;&#x9;&#x9;    proxysetheader Host              $host;&#xA;&#x9;&#x9;    proxysetheader X-Real-IP         $remoteaddr;&#xA;&#x9;&#x9;    proxysetheader X-Forwarded-For   $proxyaddxforwardedfor;&#xA;&#x9;&#x9;    proxysetheader X-Forwarded-Proto $scheme;&#xA;&#x9;&#x9;    proxysetheader X-Forwarded-Host  $host;&#xA;&#x9;&#x9;    proxysetheader X-Forwarded-Port  $serverport;&#xA;&#xA;&#x9;&#x9;    # Proxy timeouts&#xA;&#x9;&#x9;    proxyconnecttimeout              60s;&#xA;&#x9;&#x9;    proxysendtimeout                 60s;&#xA;&#x9;&#x9;    proxyreadtimeout                 60s;&#xA;&#x9;  }&#xA;}&#xA;&#xA;In our /etc/hosts, we add the following line.&#xA;&#xA;$: nano /etc/rc.conf =  127.0.0.1&#x9;music.(domain)&#xA;&#xA;Then we restarted the NGINX.&#xA;&#xA;$: service nginx restart&#xA;&#xA;If we now call up the address http://music.(domain), we see the Airsonic login screen.&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/install-airsonic-on-freebsd&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>In this tutorial, I&#39;ll explain how to install Airsonic on FreeBSD.</p>



<h2 id="what-is-airsonic" id="what-is-airsonic">What is Airsonic?</h2>

<p>It&#39;s a free, web-based media streamer that provides ubiquitous access to our music. Airsonic was developed for huge music collections. Although it&#39;s optimized for MP3 streaming, it works for any audio or video format that can be streamed over HTTP, such as. B. AAC and OGG. Using transcoder plug-ins, Airsonic supports direct conversion and streaming of virtually all audio formats including WMA, FLAC, APE, Musepack, WavPack and Shorten.</p>

<h2 id="installation" id="installation">Installation</h2>

<p>We first install <a href="https://www.freshports.org/ftp/wget/" rel="nofollow">wget</a>, <a href="https://www.freshports.org/java/openjdk11/" rel="nofollow">openjdk11</a> and <a href="https://www.freshports.org/multimedia/ffmpeg/" rel="nofollow">ffmpeg</a> with the following command:</p>

<pre><code class="language-bash">$: pkg install wget openjdk11 ffmpeg
</code></pre>

<p>Next, we create the required directories with the next commands and change them to the directory /usr/local/airsonic:</p>

<pre><code class="language-bash">$: mkdir /var/airsonic/

$: mkdir /usr/local/airsonic

$: cd /usr/local/airsonic
</code></pre>

<p>Now we can download Airsonic from their GitHub site with wget.</p>

<pre><code class="language-bash">$: wget https://github.com/airsonic/airsonic/releases/download/v10.6.2/airsonic.war
</code></pre>

<p><strong>Note:</strong> We can find the latest version <a href="https://github.com/airsonic/airsonic/releases" rel="nofollow">here</a>. Meanwhile, there is also a fork called Airsonic Advanced, which is a more modern implementation of Airsonic. More information can be found <a href="https://github.com/airsonic-advanced/airsonic-advanced" rel="nofollow">here</a>.</p>

<p>Then we have to set a system link so that Airsonic can find the FFmpeg transcoder.</p>

<pre><code class="language-bash">$: ln -s /usr/local/bin/ffmpeg /var/airsonic/transcode/ffmpeg
</code></pre>

<p>We can now start Airsonic on a test basis via the command line.</p>

<pre><code class="language-bash">$: /usr/local/bin/java -jar /usr/local/airsonic/airsonic.war
</code></pre>

<h2 id="create-a-freebsd-rc-script" id="create-a-freebsd-rc-script">Create a FreeBSD RC script</h2>

<p>Next, we want to create an rc.d script for Airsonic.</p>

<pre><code class="language-bash">$: nano /etc/rc.d/airsonic =&gt;

#!/bin/sh
#
# $FreeBSD: airsonic $
#
# PROVIDE: airsonic REQUIRE: LOGIN KEYWORD: shutdown
#
# Configuration settings for airsonic in /etc/rc.conf:
#
# airsonic_enable (bool):
# Set to &#34;NO&#34; by default. Set it to &#34;YES&#34; to enable airsonic.
#
# airsonic_home (str):
# Set to &#34;/var/airsonic&#34; by default.
#
# airsonic_host (str):
# Set to &#34;0.0.0.0&#34; by default. Specify which IP address to listen to.
#
# airsonic_port (int):
# Set to &#34;4040&#34; by default. Specify which port to listen on for HTTP(S).
#
# airsonic_context_path (str):
# Set to &#34;/&#34; by default. Specify the last part of the airsonic URL, typically &#34;/&#34; or &#34;/airsonic&#34;.
#
# airsonic_init_memory (int):
# Set to &#34;192&#34; by default. Specify the memory initial size (Java heap size) in megabytes.
#
# airsonic_max_memory (int):
# Set to &#34;384&#34; by default. Specify the memory limit (Java heap size) in megabytes.
#

. /etc/rc.subr

export LANG=en_EN.UTF-8

name=airsonic

desc=&#34;Airsonic is a free, web-based media streamer, providing ubiquitous access to your music&#34;

rcvar=${name}_enable

pidfile=&#34;/var/run/${name}.pid&#34;

load_rc_config &#34;${name}&#34;

: ${airsonic_enable:=&#34;NO&#34;}
: ${airsonic_user:=&#34;root&#34;} #: ${airsonic_user:=&#34;media&#34;}
: ${airsonic_group:=&#34;wheel&#34;} #: ${airsonic_group:=&#34;media&#34;}
: ${airsonic_home:=&#34;/var/airsonic&#34;}
: ${airsonic_address:=&#34;0.0.0.0&#34;}
: ${airsonic_port:=&#34;8080&#34;}
: ${airsonic_ssl:=&#34;NO&#34;}
: ${airsonic_context_path:=&#34;/&#34;}
: ${airsonic_init_memory:=&#34;1024&#34;}
: ${airsonic_max_memory:=&#34;2048&#34;}
: ${airsonic_chdir:=&#34;/usr/local/airsonic&#34;}

start_cmd=airsonic_start
stop_cmd=airsonic_stop
restart_cmd=airsonic_restart
status_cmd=airsonic_status
start_precmd=&#34;export LC_CTYPE=&#39;en_US.UTF-8&#39;&#34;

# -Dairsonic.defaultMusicFolder=${airsonic_home}/artists 
# -Dairsonic.defaultUploadFolder=${airsonic_home}/incoming 
# -Dairsonic.defaultPodcastFolder=${airsonic_home}/podcasts 
# -Dairsonic.defaultPlaylistImportFolder=${airsonic_home}/playlists/import 
# -Dairsonic.defaultPlaylistExportFolder=${airsonic_home}/playlists/export 
# -Dairsonic.defaultPlaylistBackupFolder=${airsonic_home}/playlists/backup \

command=&#34;/usr/sbin/daemon -p ${pidfile} -f -u ${airsonic_user}&#34;

procname=&#34;/usr/local/bin/java&#34;

command_args=&#34;-Dairsonic.home=${airsonic_home} -Dserver.address=${airsonic_address} -Dserver.port=${airsonic_port} -Dserver.context-path=${airsonic_context_path} -Xms${airsonic_init_memory}m -Xmx${airsonic_max_memory}m -Djava.awt.headless=true -jar ${airsonic_chdir}/airsonic.war&#34;

command_args1=&#34;-Dairsonic.home=${airsonic_home} -Dserver.port=${airsonic_port} -jar ${airsonic_chdir}/airsonic.war&#34;

airsonic_start() {
echo &#34;Starting Airsonic&#34;
echo &#34;${command} ${procname} ${command_args}&#34;
cd ${airsonic_chdir}
${command} ${procname} ${command_args}
}

airsonic_stop() {
echo &#34;Stopping Airsonic&#34;
kill `cat ${pidfile}`
rm ${pidfile}
}

airsonic_restart() {
airsonic_stop
sleep 1
airsonic_start
}

airsonic_status() {
if airsonic_check; then
echo &#34;Airsonic running&#34;
return 1
else
echo &#34;Airsonic not running&#34;
return 0
fi
}


airsonic_check() {
if [ -f ${pidfile} ]; then
return 0
else
return 1
fi
}

run_rc_command &#34;$1&#34;
</code></pre>

<p>We then have to make the script executable.</p>

<pre><code class="language-bash">$: chmod +x /etc/rc.d/airsonic
</code></pre>

<p>We will now activate and start Airsonic.</p>

<pre><code class="language-bash">$: service airsonic enable
$: service airsonic start
</code></pre>

<h2 id="nginx-configuration" id="nginx-configuration">NGINX configuration</h2>

<p>We use NGINX as the reverse proxy server. Likewise, we now create the following file under /usr/local/etc/nginx/vhosts:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/nginx/vhosts/airsonic.conf =&gt;

server {
    listen 80;
    server_name music.&lt;&lt;domain&gt;&gt;;

    # Proxy to the Airsonic server
    location / {
        proxy_pass 							http://127.0.0.1:8080;
        proxy_http_version                 1.1;
		    proxy_cache_bypass                 $http_upgrade;

	      # Proxy headers
		    proxy_set_header Upgrade           $http_upgrade;
		    proxy_set_header Connection        &#34;upgrade&#34;;
		    proxy_set_header Host              $host;
		    proxy_set_header X-Real-IP         $remote_addr;
		    proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
		    proxy_set_header X-Forwarded-Proto $scheme;
		    proxy_set_header X-Forwarded-Host  $host;
		    proxy_set_header X-Forwarded-Port  $server_port;

		    # Proxy timeouts
		    proxy_connect_timeout              60s;
		    proxy_send_timeout                 60s;
		    proxy_read_timeout                 60s;
	  }
}
</code></pre>

<p>In our /etc/hosts, we add the following line.</p>

<pre><code class="language-bash">$: nano /etc/rc.conf =&gt;

127.0.0.1	music.(domain)
</code></pre>

<p>Then we restarted the NGINX.</p>

<pre><code class="language-bash">$: service nginx restart
</code></pre>

<p>If we now call up the address <a href="http://music.(domain" rel="nofollow">http://music.(domain</a>), we see the Airsonic login screen.</p>

<p><img src="https://i.snap.as/2IHmcsuk.png" alt=""/></p>

<p><a href="https://remark.as/p/danschmid/install-airsonic-on-freebsd" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/install-airsonic-on-freebsd</guid>
      <pubDate>Sun, 18 Sep 2022 07:32:40 +0000</pubDate>
    </item>
    <item>
      <title>Install MySQL on FreeBSD</title>
      <link>https://danschmid.writeas.com/install-mysql-on-freebsd?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In this post, I will tell you how to install MySQL on FreeBSD.&#xA;&#xA;!--more--&#xA;&#xA;MySQL is one of the most popular relational database management systems in the world.&#xA;&#xA;So that we can install the MySQL database under FreeBSD, we need the packages mysql80-server and mysql80-client.&#xA;&#xA;We&#39;ll install the whole thing with the following command:&#xA;&#xA;$: pkg install mysql80-server mysql80-client&#xA;&#xA;We will now activate the MySQL server and start it for the first time:&#xA;&#xA;$: service mysql-server enable&#xA;$: service mysql-server start&#xA;&#xA;By default, no root password is set.&#xA;&#xA;$: mysql -u root&#xA;&#xA;mysql$: alter user &#39;root&#39;@&#39;localhost&#39; identified by &#39;your password&#39;; flush privileges; exit;&#xA;&#xA;As a final test, we will log into the newly installed MySQL server with the following statement:&#xA;&#xA;$: mysql -u root -p&#xA;&#xA;phpMyAdmin&#xA;&#xA;phpMyAdmin is a free web application for the administration of MySQL databases and their fork, MariaDB. The software is implemented in PHP, hence the name phpMyAdmin.&#xA;&#xA;We will install the phpmyadmin package with the following command:&#xA;&#xA;$: pkg install phpMyAdmin-php80&#xA;&#xA;The following hostname is entered /etc/hosts:&#xA;&#xA;127\.0.0.1 phpmyadmin.domain&#xA;&#xA;We will use NGINX as the web server. So that phpMyAdmin runs under NGINX, the following file is created under /usr/local/etc/nginx/vhosts/ under the name phpmyadmin.conf with this content:&#xA;&#xA;Server {&#xA;    listen 80;&#xA;    servername phpmyadmin.domain;&#xA;&#xA;    root /usr/local/www/phpMyAdmin/;&#xA;    index index.php;&#xA;&#xA;    location ~\.php$ {&#xA;        tryfiles $uri = 404;&#xA;        fastcgisplitpathinfo ^(.+\.php)(/.+)$;&#xA;        fastcgipass unix:/var/run/php-fpm.sock;&#xA;        fastcgiindex index.php;&#xA;        fastcgiparam SCRIPTFILENAME $requestfilename;&#xA;        include fastcgi_params;&#xA;    }&#xA;}&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/install-mysql-on-freebsd&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>In this post, I will tell you how to install MySQL on FreeBSD.</p>



<p>MySQL is one of the most popular relational database management systems in the world.</p>

<p>So that we can install the MySQL database under FreeBSD, we need the packages <a href="https://www.freshports.org/databases/mysql80-server/" rel="nofollow">mysql80-server</a> and <a href="https://www.freshports.org/databases/mysql80-client/" rel="nofollow">mysql80-client</a>.</p>

<p>We&#39;ll install the whole thing with the following command:</p>

<pre><code class="language-bash">$: pkg install mysql80-server mysql80-client
</code></pre>

<p>We will now activate the MySQL server and start it for the first time:</p>

<pre><code class="language-bash">$: service mysql-server enable
$: service mysql-server start
</code></pre>

<p>By default, no root password is set.</p>

<pre><code class="language-bash">$: mysql -u root

mysql$: alter user &#39;root&#39;@&#39;localhost&#39; identified by &#39;your password&#39;; flush privileges; exit;
</code></pre>

<p>As a final test, we will log into the newly installed MySQL server with the following statement:</p>

<pre><code class="language-bash">$: mysql -u root -p
</code></pre>

<h2 id="phpmyadmin" id="phpmyadmin">phpMyAdmin</h2>

<p>phpMyAdmin is a free web application for the administration of MySQL databases and their fork, MariaDB. The software is implemented in PHP, hence the name phpMyAdmin.</p>

<p>We will install the <a href="https://www.freshports.org/databases/phpmyadmin" rel="nofollow">phpmyadmin</a> package with the following command:</p>

<pre><code class="language-bash">$: pkg install phpMyAdmin-php80
</code></pre>

<p>The following hostname is entered /etc/hosts:</p>

<p>127.0.0.1 phpmyadmin.domain</p>

<p>We will use NGINX as the web server. So that phpMyAdmin runs under NGINX, the following file is created under /usr/local/etc/nginx/vhosts/ under the name phpmyadmin.conf with this content:</p>

<pre><code class="language-bash">Server {
    listen 80;
    server_name phpmyadmin.domain;

    root /usr/local/www/phpMyAdmin/;
    index index.php;

    location ~\.php$ {
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        include fastcgi_params;
    }
}
</code></pre>

<p><a href="https://remark.as/p/danschmid/install-mysql-on-freebsd" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/install-mysql-on-freebsd</guid>
      <pubDate>Sun, 18 Sep 2022 07:03:00 +0000</pubDate>
    </item>
    <item>
      <title>Install PHP on FreeBSD</title>
      <link>https://danschmid.writeas.com/install-php-on-freebsd?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[This is a tutorial on how to use PHP on FreeBSD.&#xA;&#xA;!--more--&#xA;&#xA;PHP, which stands for “PHP: Hypertext Preprocessor”, is a widely used open source, general-purpose scripting language that is particularly suitable for web development and can be embedded in HTML. The syntax is based on C, Java, and Perl, and is easy to learn.&#xA;&#xA;This is a tutorial on how to use PHP on FreeBSD. We will install the following packages:&#xA;&#xA;php80&#xA;php80-dom&#xA;php80-gd&#xA;php80-phar&#xA;php80-ctype&#xA;php80-filter&#xA;php80-iconv&#xA;php80-curl&#xA;php80-mysqli&#xA;php80-pdomysql&#xA;php80-sqlite3&#xA;php80-pdosqlite&#xA;php80-tokenizer&#xA;php80-readline&#xA;php80-session&#xA;php80-simplexml&#xA;php80-xml&#xA;php80-zip&#xA;php80-zlib&#xA;php80-bcmath&#xA;php80-xmlwriter&#xA;php80-posix&#xA;php80-openssl&#xA;pecl-redis&#xA;php80-fileinfo&#xA;php80-soap&#xA;openssl&#xA;&#xA;For this, we will run the following command:&#xA;&#xA;$: pkg install php80 php80-dom php80-gd php80-phar php80-ctype php80-filter php80-iconv php80-json php80-curl php80-mysqli php80-pdomysql php80-sqlite3 php80-pdosqlite php80-tokenizer php80-readline php80-session php80-simplexml php80-xml php80-zip php80-zlib php80-bcmath php80-xmlwriter php80-posix php80-openssl php80-pecl-redis php80-fileinfo php80-soap openssl&#xA;&#xA;Then we copy the php.ini-production template:&#xA;&#xA;$: cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini&#xA;&#xA;We will next edit the www conf:&#xA;&#xA;$: nano /usr/local/etc/php-fpm.d/www.conf ⇒&#xA;&#xA;listen = /var/run/php-fpm.sock&#xA;listen.owner = www&#xA;listen.group = www&#xA;listen.mode = 0660&#xA;&#xA;In the /usr/local/etc/php.ini file, we need to find a section that configures the behavior of cgi.fixpathinfo. It is commented out and set to “1” by default. We have to comment this out and set it to “0”. This prevents PHP from attempting to execute parts of the path if the file passed to process is not found. This could be used by malicious users to execute arbitrary code.&#xA;&#xA;$: nano /usr/local/etc/php.ini ⇒&#xA;&#xA;cgi.fixpathinfo=0&#xA;&#xA;Finally, we will activate PHP and start the PHP service:&#xA;&#xA;$: service php-fpm enable&#xA;$: service php-fpm start&#xA;&#xA;PHPUnit&#xA;&#xA;PHPUnit is a free framework written in PHP for testing PHP scripts, which is particularly suitable for automated tests of individual units.&#xA;&#xA;So that we can use PHPUnit under FreeBSD, we install the package phpunit8 with the following command:&#xA;&#xA;$: pkg install phpunit8-php80&#xA;&#xA;Composer&#xA;&#xA;Composer is an application-oriented package manager for the PHP programming language. Composer executed via the command line and installs dependencies of a PHP program.&#xA;&#xA;We install php-composer2 with the following command:&#xA;&#xA;$: pkg install php80-composer2&#xA;&#xA;Xdebug&#xA;&#xA;Xdebug helps us debug our PHP scripts by providing a lot of valuable debug information.&#xA;&#xA;We installed the pecl-xdebug extension with:&#xA;&#xA;$: pkg install php80-pecl-xdebug&#xA;&#xA;Then we add the following instructions to php.ini:&#xA;&#xA;$: nano /usr/local/etc/php.ini ⇒&#xA;&#xA;xdebug.remoteenable=1&#xA;xdebug.remoteport=9000&#xA;&#xA;Finally, we restart the PHP service:&#xA;&#xA;$: service php-fpm restart&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/install-php-on-freebsd&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>This is a tutorial on how to use PHP on FreeBSD.</p>



<p>PHP, which stands for “PHP: Hypertext Preprocessor”, is a widely used open source, general-purpose scripting language that is particularly suitable for web development and can be embedded in HTML. The syntax is based on C, Java, and Perl, and is easy to learn.</p>

<p>This is a tutorial on how to use PHP on FreeBSD. We will install the following packages:</p>
<ul><li><a href="https://www.freshports.org/lang/php80" rel="nofollow">php80</a></li>
<li><a href="https://www.freshports.org/textproc/php80-dom" rel="nofollow">php80-dom</a></li>
<li><a href="https://www.freshports.org/graphics/php80-gd" rel="nofollow">php80-gd</a></li>
<li><a href="https://www.freshports.org/archivers/php80-phar" rel="nofollow">php80-phar</a></li>
<li><a href="https://www.freshports.org/textproc/php80-ctype" rel="nofollow">php80-ctype</a></li>
<li><a href="https://www.freshports.org/security/php80-filter" rel="nofollow">php80-filter</a></li>
<li><a href="https://www.freshports.org/converters/php80-iconv" rel="nofollow">php80-iconv</a></li>
<li><a href="https://www.freshports.org/ftp/php80-curl" rel="nofollow">php80-curl</a></li>
<li><a href="https://www.freshports.org/databases/php80-mysqli" rel="nofollow">php80-mysqli</a></li>
<li><a href="https://www.freshports.org/databases/php80-pdo_mysql" rel="nofollow">php80-pdo_mysql</a></li>
<li><a href="https://www.freshports.org/databases/php80-sqlite3" rel="nofollow">php80-sqlite3</a></li>
<li><a href="https://www.freshports.org/databases/php80-pdo_sqlite" rel="nofollow">php80-pdo_sqlite</a></li>
<li><a href="https://www.freshports.org/devel/php80-tokenizer" rel="nofollow">php80-tokenizer</a></li>
<li><a href="https://www.freshports.org/devel/php80-readline" rel="nofollow">php80-readline</a></li>
<li><a href="https://www.freshports.org/www/php80-session" rel="nofollow">php80-session</a></li>
<li><a href="https://www.freshports.org/textproc/php80-simplexml" rel="nofollow">php80-simplexml</a></li>
<li><a href="https://www.freshports.org/textproc/php80-xml" rel="nofollow">php80-xml</a></li>
<li><a href="https://www.freshports.org/archivers/php80-zip" rel="nofollow">php80-zip</a></li>
<li><a href="https://www.freshports.org/archivers/php80-zlib" rel="nofollow">php80-zlib</a></li>
<li><a href="https://www.freshports.org/math/php80-bcmath" rel="nofollow">php80-bcmath</a></li>
<li><a href="https://www.freshports.org/textproc/php80-xmlwriter" rel="nofollow">php80-xmlwriter</a></li>
<li><a href="https://www.freshports.org/sysutils/php80-posix" rel="nofollow">php80-posix</a></li>
<li><a href="https://www.freshports.org/security/php80-openssl" rel="nofollow">php80-openssl</a></li>
<li><a href="https://www.freshports.org/databases/pecl-redis" rel="nofollow">pecl-redis</a></li>
<li><a href="https://www.freshports.org/sysutils/php80-fileinfo" rel="nofollow">php80-fileinfo</a></li>
<li><a href="https://www.freshports.org/net/php80-soap" rel="nofollow">php80-soap</a></li>
<li><a href="https://www.freshports.org/security/openssl" rel="nofollow">openssl</a></li></ul>

<p>For this, we will run the following command:</p>

<pre><code class="language-bash">$: pkg install php80 php80-dom php80-gd php80-phar php80-ctype php80-filter php80-iconv php80-json php80-curl php80-mysqli php80-pdo_mysql php80-sqlite3 php80-pdo_sqlite php80-tokenizer php80-readline php80-session php80-simplexml php80-xml php80-zip php80-zlib php80-bcmath php80-xmlwriter php80-posix php80-openssl php80-pecl-redis php80-fileinfo php80-soap openssl
</code></pre>

<p>Then we copy the php.ini-production template:</p>

<pre><code class="language-bash">$: cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini
</code></pre>

<p>We will next edit the www conf:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/php-fpm.d/www.conf ⇒

listen = /var/run/php-fpm.sock
listen.owner = www
listen.group = www
listen.mode = 0660
</code></pre>

<p>In the /usr/local/etc/php.ini file, we need to find a section that configures the behavior of cgi.fix_pathinfo. It is commented out and set to “1” by default. We have to comment this out and set it to “0”. This prevents PHP from attempting to execute parts of the path if the file passed to process is not found. This could be used by malicious users to execute arbitrary code.</p>

<pre><code class="language-bash">$: nano /usr/local/etc/php.ini ⇒

cgi.fix_pathinfo=0
</code></pre>

<p>Finally, we will activate PHP and start the PHP service:</p>

<pre><code class="language-bash">$: service php-fpm enable
$: service php-fpm start
</code></pre>

<h2 id="phpunit" id="phpunit">PHPUnit</h2>

<p>PHPUnit is a free framework written in PHP for testing PHP scripts, which is particularly suitable for automated tests of individual units.</p>

<p>So that we can use PHPUnit under FreeBSD, we install the package <a href="https://www.freshports.org/devel/phpunit8/" rel="nofollow">phpunit8</a> with the following command:</p>

<pre><code class="language-bash">$: pkg install phpunit8-php80
</code></pre>

<h2 id="composer" id="composer">Composer</h2>

<p>Composer is an application-oriented package manager for the PHP programming language. Composer executed via the command line and installs dependencies of a PHP program.</p>

<p>We install <a href="https://www.freshports.org/devel/php-composer2" rel="nofollow">php-composer2</a> with the following command:</p>

<pre><code class="language-bash">$: pkg install php80-composer2
</code></pre>

<h2 id="xdebug" id="xdebug">Xdebug</h2>

<p>Xdebug helps us debug our PHP scripts by providing a lot of valuable debug information.</p>

<p>We installed the <a href="https://www.freshports.org/devel/pecl-xdebug" rel="nofollow">pecl-xdebug</a> extension with:</p>

<pre><code class="language-bash">$: pkg install php80-pecl-xdebug
</code></pre>

<p>Then we add the following instructions to php.ini:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/php.ini ⇒

xdebug.remote_enable=1
xdebug.remote_port=9000
</code></pre>

<p>Finally, we restart the PHP service:</p>

<pre><code class="language-bash">$: service php-fpm restart
</code></pre>

<p><a href="https://remark.as/p/danschmid/install-php-on-freebsd" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/install-php-on-freebsd</guid>
      <pubDate>Sun, 18 Sep 2022 06:18:01 +0000</pubDate>
    </item>
    <item>
      <title>Poudriere Guide</title>
      <link>https://danschmid.writeas.com/poudriere-guide?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[This blog post describes how to set up and use the Poudriere Build System.&#xA;&#xA;!--more--&#xA;&#xA;The port&#39;s system is one of FreeBSD&#39;s greatest advantages for users who want flexibility and control over their software. It enables administrators to easily create and manage source-based installations using a system that is robust and predictable.&#xA;&#xA;While the benefits of this feature are great, some of the most common complaints against port-based management are the time and resources it takes to compile each software program. This becomes even more of a problem when you manage many servers, each compiling its ports. While FreeBSD packages offer an alternative that speeds installation, they sacrifice control that ports allow.&#xA;&#xA;To resolve this issue, administrators can use an application called Poudriere to create and manage custom packages. While technically designed to package a wide variety of architectures, Poudriere is often used as a packaging environment to package and host an entire infrastructure of FreeBSD servers.&#xA;&#xA;Install the required packages&#xA;&#xA;In the beginning, we will install all the required ports.&#xA;&#xA;First, we have to install Poudriere.&#xA;&#xA;$: pkg install poudriere&#xA;&#xA;Finally, we also want to install a web server. This will serve two purposes. First, this will be the method by which our machines will be able to download the packages that we will be compiling. Second, Poudriere provides a web interface, so we can track the build process and monitor logs. In our case, we use the NGINX web server:&#xA;&#xA;$: pkg install nginx&#xA;&#xA;Create an SSL certificate and key&#xA;&#xA;When we build packages with Poudriere, we want to be able to sign them with a private key. This ensures that all of our machines legitimize the packets created and that nobody intercepts the connection to the built computer to send malicious packets.&#xA;&#xA;We&#39;re going to make sure we have an SSL directory that has two subdirectories called keys and certs. We can do this in one command by typing:&#xA;&#xA;$: mkdir -p /usr/local/etc/ssl/{keys,certs}&#xA;&#xA;Our private key, which must be kept secret, is stored in the key directory. This will be used to sign the packages we are going to create. We can lock the directory so that users without root or sudo privileges cannot interact with the directory or its contents:&#xA;&#xA;$: chmod 0600 /usr/local/etc/ssl/keys&#xA;&#xA;Next, we create a 4096-bit key, called poudriere.key, and place it in our key&#39;s directory by typing:&#xA;&#xA;$: openssl genrsa -out /usr/local/etc/ssl/keys/poudriere.key 4096&#xA;&#xA;After the key has been generated, we can create a public certificate from it by typing:&#xA;&#xA;$: openssl rsa -in /usr/local/etc/ssl/keys/poudriere.key -pubout -out /usr/local/etc/ssl/certs/poudriere.cert&#xA;&#xA;We now have the SSL components we need to sign packets and verify the signatures. Later, we will configure our clients to use the generated certificate for package verification.&#xA;&#xA;Configuring Poudriere&#xA;&#xA;Now that we have our SSL certificate and key, we can start configuring Poudriere.&#xA;&#xA;The main configuration file located at /usr/local/etc/poudriere.conf. We open this file:&#xA;&#xA;$: nano /usr/local/etc/poudriere.conf&#xA;&#xA;The Poudriere configuration file is very well commented and most of the settings must be predefined. We&#39;ll be making some specific changes, but leaving the majority of them intact.&#xA;&#xA;If we use UFS as the file system, the following option must be commented out:&#xA;&#xA;NOZFS=yes&#xA;&#xA;On the other hand, if our server uses ZFS, we can configure Poudriere to use a specific pool by setting the ZPOOL option. In this pool, we can specify the trunk that Poudriere should use for packets, protocols, etc. with the ZROOTFS option. Note that these two options should not be set when the NOZFS option is set to “yes”:&#xA;&#xA;NOZFS=yes&#xA;ZPOOL=tank&#xA;ZROOTFS=/poudriere&#xA;&#xA;When building software, Poudriere uses some type of jail to separate the build system from the main operating system. Next, we need to fill in a valid host where the build machine can download the software it needs to do the jails. This is configured via the FREEBSDHOST option.&#xA;&#xA;This option should already exist, even though it is not currently set to a valid host. We can change this to the default path. ftp://ftp.freebsd.org or use a narrower mirror if we know one:&#xA;&#xA;FREEBSDHOST=https://download.freebsd.org&#xA;&#xA;Next, we want to be sure that our data directory is set correctly within the Poudriere root. This is controlled with the POUDRIEREDATA option and&#xA;should be set by default. However, we&#39;ll comment on the option to be certain:&#xA;&#xA;POUDRIEREDATA=${BASEFS}/data&#xA;&#xA;The next options that we should comment on are the CHECKCHANGEDOPTIONS and CHECKCHANGEDDEPS options. The first option tells Poudriere to rebuild packages if the options for them have changed. The second option tells Poudriere to rebuild packages if dependencies have changed since the last compilation.&#xA;&#xA;Both options exist in the form we want in the configuration file. We just have to comment them out:&#xA;&#xA;CHECKCHANGEDOPTIONS=verbose&#xA;CHECKCHANGEDDEPS=yes&#xA;&#xA;Next, we&#39;re going to point Poudriere at the SSL key we created so that packages can be signed during the build. The option used to specify is called PKGREPOSIGNINGKEY. We will uncheck this option and change the path to reflect the location of the SSL key we created earlier:&#xA;&#xA;PKGREPOSIGNINGKEY=/usr/local/etc/ssl/keys/poudriere.key&#xA;&#xA;Finally, we can set the URLBASE string to the domain name or IP address where our server can be reached. This is used by Poudriere to create links in the output that can be clicked. We should include the log and end the value with a slash:&#xA;&#xA;URLBASE=http://serverdomainorIP/&#xA;&#xA;When we&#39;re done making changes, we&#39;ll save and close the file.&#xA;&#xA;Create the built environment&#xA;&#xA;Next, we need to design our built environment. As mentioned earlier, Poudriere will build ports in an isolated environment with jails.&#xA;&#xA;For our purposes, our jails build command looks like this:&#xA;&#xA;$: poudriere jail -c -j 13-0x64 -v 13.0-RELEASE&#xA;&#xA;This will take a while, so be patient. When done, we can see the one installed by typing:&#xA;&#xA;$: poudriere jail -l&#xA;&#xA;Output:&#xA;&#xA;JAILNAME        VERSION         ARCH  METHOD TIMESTAMP           PATH&#xA;&#xA;13-0x64 13.0-RELEASE-p2 amd64 ftp    2021-01-06 20:43:48 /usr/local/poudriere/jails/13-0x64&#xA;&#xA;Once we&#39;ve created a jail, we need to install a port structure.&#xA;&#xA;We can use the -p flag to name our ports tree. We will name our tree HEAD because it summarizes exactly using this tree (the &#34;head&#34; or the most current point of the tree). Likewise, we will update it regularly so that it corresponds to the most current version of the available ports structure:&#xA;&#xA;$: poudriere ports -c -m git+https -B main -p HEAD&#xA;&#xA;This procedure will also take a while because the entire port structure has to be fetched and extracted. When this is done, we can view our port&#39;s tree by typing:&#xA;&#xA;$: poudriere ports -l&#xA;&#xA;Now that this step is complete, we have the structures to compile our ports and build packages. Next, we can start by putting together our list of ports to create and configure the options we need for each software.&#xA;&#xA;Create a port building list and set port options&#xA;&#xA;We are going to make a list of ports that we can pass directly to Poudriere.&#xA;&#xA;The file should list the port category followed by a slash and the port name to reflect its position in the ports tree:&#xA;&#xA;portcategory/firstport&#xA;portcategory/secondport&#xA;portcategory/thirdport&#xA;&#xA;All necessary dependencies are also created automatically. So, we don&#39;t need to track down the entire dependency structure of the ports that we want to install. We can create this file manually, but if our base system already has most of the software installed, we can create the file automatically.&#xA;&#xA;Before we do this, it is usually a good idea to remove any unnecessary dependencies from our system to keep the port list as clean as possible. We can do this by typing:&#xA;&#xA;$: pkg autoremove&#xA;&#xA;Thereafter, we can get a list of the software that we have explicitly installed on our build system:&#xA;&#xA;$: pkg query -e &#34;%a==0&#34; &#34;%o&#34; | sort -d | tee /usr/local/etc/poudriere.d/port-list&#xA;&#xA;If there are ports that we don&#39;t want to add, we&#39;ll remove the associated line. This is also an opportunity to add additional ports that we may need.&#xA;&#xA;If we use certain make.conf options to create our ports, we can create a make.conf file for each jail within our /usr/local/etc/poudriere.d directory. For example, we can create a make.conf file for our jail with this name:&#xA;&#xA;$: nano /usr/local/etc/poudriere.d/13-0x64-make.conf&#xA;&#xA;I prefer to create a global make.conf that is valid for all jails.&#xA;&#xA;$: nano /usr/local/etc/poudriere.d/make.conf&#xA;&#xA;Inside, we can specify all the options we want to use when creating our ports. For example, if we prefer not to build documentation, samples, native language support, or X11 support, we can specify:&#xA;&#xA;OPTIONSUNSET+= DOCS NLS X11 EXAMPLES&#xA;&#xA;We can also specify DefaultVersions. In my case, it looks like this:&#xA;&#xA;DEFAULTVERSIONS+= mysql=8.0 php=8.0&#xA;&#xA;In this case, all packages and/or their dependencies are built with the specified version.&#xA;&#xA;Subsequently, we can configure any of our ports that will create files with the options selected.&#xA;&#xA;We can configure anything that has not yet been configured with the options command. We should pass both the port tree we created (with the -p option) and the jail for which we set these options (with the -j option). Not only that, but we also need to provide the list of ports we want to configure with the -f option.&#xA;&#xA;$: poudriere options -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list&#xA;&#xA;We see a dialog for each of the ports in the list and all dependencies for which no corresponding options are set in the -options directory. The information in our make.conf file is preselected in the selection screens. We&#39;ll select all the options we want to use.&#xA;&#xA;If we want to reconfigure the options for our ports in the future, we can run the above command again with the -c option. This will show us all the available configuration options, regardless of whether we have made a selection in the past:&#xA;&#xA;$: poudriere options -c -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list&#xA;&#xA;Build the ports&#xA;&#xA;Now we&#39;re finally ready to start building ports.&#xA;&#xA;We enter the following to update the jail:&#xA;&#xA;$: poudriere jail -u -j 13-0x64&#xA;&#xA;Then we enter the following to update the ports structure:&#xA;&#xA;$: poudriere ports -u -p HEAD&#xA;&#xA;Once that is done, we can start the build process.&#xA;&#xA;Note: this can be a very long process. If we are connected to the server via SSH, we recommend installing the screen package and starting a session:&#xA;&#xA;$: pkg install screen&#xA;$: rehash&#xA;$: screen&#xA;&#xA;To start the build, we just need to use the bulk command and point to all of the individual parts that we have configured. If we&#39;ve used the values in this guide, the command looks like this:&#xA;&#xA;$: poudriere bulk -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list&#xA;&#xA;This starts with many workers (depending on our poudriere.conf file or the number of CPUs available) and starts building the ports.&#xA;&#xA;At any time during the creation process, we can get information about the progress by holding down the CTRL key and pressing t.&#xA;&#xA;Certain parts of the process produce more output than others.&#xA;&#xA;Setting up NGINX  for providing the front end and the repository&#xA;&#xA;For this step, the NGINX must be set up with virtual hosts.&#xA;&#xA;The following hostname entered /etc/hosts:&#xA;&#xA;127.0.0.1 bsd. «Domain»&#xA;&#xA;For Poudriere to run under NGINX, the following file created under /usr/local/etc/nginx/vhosts/ under the name poudriere.conf with this content:&#xA;&#xA;server {&#xA;  listen 80 default;&#xA;  servername bsd.  domain  ;&#xA;  root /usr/local/share/poudriere/html;&#xA;&#xA;  location /data {&#xA;    alias /usr/local/poudriere/data/logs/bulk;&#xA;    autoindex on;&#xA;  }&#xA;&#xA;  location /packages {&#xA;    root /usr/local/poudriere/data;&#xA;    autoindex on;&#xA;  }&#xA;}&#xA;&#xA;Then restart the NGINX:&#xA;&#xA;$: service nginx restart&#xA;&#xA;Next, we&#39;re going to make a small change to our mime.types file. If we click on a log in the web browser with the current settings, the file is downloaded and not displayed as normal text. We can change this behavior by marking files with the extension .log. as plain text files.&#xA;&#xA;We open the file mime.types in our text editor:&#xA;&#xA;$: nano /usr/local/etc/nginx/mime.types&#xA;&#xA;We find the entry indicating the text / plain content type, and append the log to the end of the current list of file types separated by a space:&#xA;&#xA;text/mathml                         mml;&#xA;text/plain                          txt log;&#xA;text/vnd.sun.j2me.app-descriptor    jad;&#xA;&#xA;Now, we can display the Poudriere web interface by going to the domain name or the IP address of our server in our web browser, bsd.«domain».&#xA;&#xA;Configure package clients&#xA;&#xA;Now that we have created packages and configured a repository to host our packages, we can configure our clients to use our server as a package source.&#xA;&#xA;Configure the build server to use the own package repo&#xA;&#xA;We can start by configuring the build server to use the packages it built.&#xA;&#xA;First, we need to create a directory for our repository configuration files:&#xA;&#xA;$: mkdir -p /usr/local/etc/pkg/repos&#xA;&#xA;In this directory, we can create our repository configuration file. It must end in .conf, so we&#39;ll call it poudriere.conf to make its purpose cleaner:&#xA;&#xA;$: nano /usr/local/etc/pkg/repos/poudriere.conf =  poudriere: {&#xA;  url: &#34;file:///usr/local/poudriere/data/packages/13-0x64-HEAD&#34;,&#xA;  mirrortype: &#34;srv&#34;,&#xA;  signaturetype: &#34;pubkey&#34;,&#xA;  pubkey: &#34;/usr/local/etc/ssl/certs/poudriere.cert&#34;,&#xA;  enabled: yes,&#xA;  priority: 100&#xA;}&#xA;&#xA;If we only select packages that we have created ourselves (the more secure option), we can omit the priority setting, but we should disable the default repositories. We can do this by creating another repo file that will overwrite the default repository file and disable it:&#xA;&#xA;$: nano /usr/local/etc/pkg/repos/freebsd.conf =  FreeBSD: {&#xA;  enabled: no&#xA;}&#xA;&#xA;Regardless of our configuration choices, we should now be ready to use our repository. We&#39;ll update our package list by entering:&#xA;&#xA;$: pkg update&#xA;&#xA;Now, our server can use the pkg command to install packages from our local repository.&#xA;&#xA;Configure remote clients to use your build machine&#39;s repository&#xA;&#xA;One of the most compelling reasons to set up Poudriere on a build machine is to use that host as a repository for many other machines. All we have to do to get this working is to download the public SSL certificate from our build machine and set up a similar repository definition.&#xA;&#xA;To connect to our build host from our client computers, we should start an SSH agent on our local computer to store our SSH key credentials.&#xA;&#xA;We need to add our SSH key by typing:&#xA;&#xA;$: ssh-add&#xA;&#xA;Then, we first have to create the directory structure (if it doesn&#39;t exist) so that we can save the certificate. We&#39;ll go ahead and create a directory for keys so we can use it for future tasks:&#xA;&#xA;$: mkdir -p /usr/local/etc/ssl/{keys,certs}&#xA;&#xA;Now we can connect to our build machine with SSH and send the certificate file back to our client machine. Since we&#39;ve forwarded our SSH credentials, we should be able to do this without asking for a password:&#xA;&#xA;$: ssh user@serverdomainorIP &#39;cat /usr/local/etc/ssl/certs/poudriere.cert&#39; | tee /usr/local/etc/ssl/certs/poudriere.cert&#xA;&#xA;This command connects to the build machine from our client computer using our local SSH credentials. As soon as the connection is established, it shows the content of your certificate file and directs us through the SSH tunnel back to our remote client computer. From there, we use the tee combination to write the certificate into our directory.&#xA;&#xA;Once this is done, we can create our repository directory structure, like on the build machine itself:&#xA;&#xA;$: mkdir -p /usr/local/etc/pkg/repos&#xA;&#xA;Now, we can create a repository file similar to the one used on the build machine:&#xA;&#xA;$: nano /usr/local/etc/pkg/repos/poudriere.conf =  poudriere: {&#xA;  url: &#34;https://serverdomainorIP/packages/13-0x64-HEAD/&#34;,&#xA;  mirrortype: &#34;https&#34;,&#xA;  signaturetype: &#34;pubkey&#34;,&#xA;  pubkey: &#34;/usr/local/etc/ssl/certs/poudriere.cert&#34;,&#xA;  enabled: yes,&#xA;  priority: 100&#xA;}&#xA;&#xA;If we just want to use our compiled packages, the file should look something like this:&#xA;&#xA;poudriere: {&#xA;  url: &#34;https://serverdomainorIP/packages/13-0x64-HEAD/&#34;,&#xA;  mirrortype: &#34;https&#34;,&#xA;  signaturetype: &#34;pubkey&#34;,&#xA;  pubkey: &#34;/usr/local/etc/ssl/certs/poudriere.cert&#34;,&#xA;  enabled: yes&#xA;}&#xA;&#xA;If we only want to use our packages, we must remember to create a different repository configuration file to override the default FreeBSD repository configuration:&#xA;&#xA;$: nano /usr/local/etc/pkg/repos/freebsd.conf =  FreeBSD: {&#xA;  enabled: no&#xA;}&#xA;&#xA;After we&#39;re done, let&#39;s update our pkg database to start using our custom compiled packages:&#xA;&#xA;$: pkg update&#xA;&#xA;Cron job&#xA;&#xA;So that Poudriere automatically updates the jails and builds the packages, we will set up a cron job.&#xA;&#xA;We create the following file under /usr/local/etc/poudriere.d/scripts:&#xA;&#xA;$: mkdir /usr/local/etc/poudriere.d/scripts&#xA;&#xA;$: nano /usr/local/etc/poudriere.d/scripts/poudriere-cron.sh =  #!/bin/sh&#xA;&#xA;SCRIPTNAME=basename &#34;$0&#34;&#xA;&#xA;check for running script&#xA;STATUS=ps ax | grep &#34;$SCRIPTNAME&#34; | grep -v grep | wc -l&#xA;&#xA;compare to 2 because the ` create a subprocess&#xA;if [ &#34;$STATUS&#34; -gt 2 ]; then&#xA;  echo &#34;already running ... exit&#34;&#xA;  exit 0&#xA;fi&#xA;&#xA;The build&#xA;POUDRIERE=&#34;/usr/local/bin/poudriere&#34;&#xA;PORTLIST=&#34;/usr/local/etc/poudriere.d/port-list&#34;&#xA;JAILS=&#34;13-0x64&#34;&#xA;REPOS=&#34;HEAD&#34;&#xA;URL=&#34;https://bsd.&lt;domain  &#34;&#xA;&#xA;poudrierebuild() {&#xA;    for JAIL in $JAILS; do&#xA;      for REPO in $REPOS; do&#xA;        echo &#34;Started $JAIL / $REPO / $SET (&#34;/bin/date | /usr/bin/tr -d &#39;\n&#39;&#34;)&#34;&#xA;        &#34;$POUDRIERE&#34; bulk -j &#34;$JAIL&#34; -z &#34;$SET&#34; -p &#34;$REPO&#34;  -f &#34;$PORTLIST&#34;   /dev/null&#xA;        echo &#34;    Cleaning $REPO (&#34;/bin/date | /usr/bin/tr -d &#39;\n&#39;&#34;)&#34;&#xA;        &#34;$POUDRIERE&#34; pkgclean -j &#34;$JAIL&#34; -z &#34;$SET&#34; -p &#34;$REPO&#34; -f &#34;$PORTLIST&#34; -y   /dev/null&#xA;        echo &#34;    Finished $REPO (&#34;/bin/date | /usr/bin/tr -d &#39;\n&#39;&#34;)&#34;&#xA;      done&#xA;    done&#xA;}&#xA;&#xA;reposupdate() {&#xA;  echo &#34;[$SCRIPTNAME] Updating ports tree...&#34;&#xA;&#xA;  for REPO in $REPOS; do&#xA;    echo &#34;[$SCRIPTNAME] Updating ports tree... $REPO&#34;&#xA;    &#34;$POUDRIERE&#34; ports -p &#34;$REPO&#34; -u   /dev/null&#xA;&#xA;    if [ $? -ne 0 ]; then&#xA;      echo &#34;    Error updating ports tree.&#34;&#xA;      exit 1&#xA;    fi&#xA;&#xA;  echo &#34;    Ports tree has been updated.&#34;&#xA;  done&#xA;}&#xA;&#xA;echo &#34;This is a log of poudriere. Details: $URL&#34;&#xA;echo &#34;&#34;&#xA;&#xA;reposupdate&#xA;poudriere_build&#xA;&#xA;echo &#34;[$SCRIPTNAME] Cleaning distfiles...&#34;&#xA;&#34;$POUDRIERE&#34; distclean -p &#34;$REPOS&#34; -f &#34;$PORTLIST&#34; -y   /dev/null&#xA;&#xA;echo &#34;[$SCRIPTNAME] Finished. (&#34;/bin/date | /usr/bin/tr -d &#39;\n&#39;&#34;)&#34;&#xA;exit 0&#xA;&#xA;Then make it executable:&#xA;&#xA;$: chmod +x /usr/local/etc/poudriere.d/scripts/poudriere-cron.sh&#xA;&#xA;Then we should run the script once to test whether everything works correctly.&#xA;&#xA;If everything fits, we can include it in the /etc/crontab as follows:&#xA;&#xA;§: nano /etc/crontab =  10      0                            root    /usr/local/etc/poudriere.d/scripts/poudriere-cron.sh&#xA;&#xA;The build process will then run every night. If we have packages such as Chromium where the build takes longer than 24 hours, it can be adjusted here.&#xA;&#xA;Command list&#xA;&#xA;Poudriere make.conf&#xA;&#xA;$: nano /usr/local/etc/poudriere.d/make.conf&#xA;&#xA;Poudriere conf&#xA;&#xA;$: nano /usr/local/etc/poudriere.conf&#xA;&#xA;Portlist&#xA;&#xA;$: nano  /usr/local/etc/poudriere.d/port-list&#xA;&#xA;Create a new jail&#xA;&#xA;$: poudriere jail -c -j 13-0x64 -v 12.0-RELEASE&#xA;&#xA;Update a jail&#xA;&#xA;$: poudriere jail -u -j 13-0x64&#xA;&#xA;Update ports&#xA;&#xA;$: poudriere ports -u -p HEAD&#xA;&#xA;Remove unused packages&#xA;&#xA;$: poudriere pkgclean -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list&#xA;&#xA;Set options for the port list&#xA;&#xA;$: poudriere options -c -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list&#xA;&#xA;Set options for a package&#xA;&#xA;$: poudriere options -c -j 13-0x64 -p HEAD  databases/mariadb103-client&#xA;&#xA;Build packages without a cronjob&#xA;&#xA;$: poudriere bulk -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list&#xA;&#xA;When upgrading the system, copy the options to the new version&#xA;&#xA;$: cp -R /usr/local/etc/poudriere.d/12-2x64-HEAD-options/. /usr/local/etc/poudriere.d/13-0x64-HEAD-options/&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/poudriere-guide&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>This blog post describes how to set up and use the Poudriere Build System.</p>



<p>The port&#39;s system is one of FreeBSD&#39;s greatest advantages for users who want flexibility and control over their software. It enables administrators to easily create and manage source-based installations using a system that is robust and predictable.</p>

<p>While the benefits of this feature are great, some of the most common complaints against port-based management are the time and resources it takes to compile each software program. This becomes even more of a problem when you manage many servers, each compiling its ports. While FreeBSD packages offer an alternative that speeds installation, they sacrifice control that ports allow.</p>

<p>To resolve this issue, administrators can use an application called <a href="https://www.freshports.org/ports-mgmt/poudriere" rel="nofollow">Poudriere</a> to create and manage custom packages. While technically designed to package a wide variety of architectures, Poudriere is often used as a packaging environment to package and host an entire infrastructure of FreeBSD servers.</p>

<h2 id="install-the-required-packages" id="install-the-required-packages">Install the required packages</h2>

<p>In the beginning, we will install all the required ports.</p>

<p>First, we have to install Poudriere.</p>

<pre><code class="language-bash">$: pkg install poudriere
</code></pre>

<p>Finally, we also want to install a web server. This will serve two purposes. First, this will be the method by which our machines will be able to download the packages that we will be compiling. Second, Poudriere provides a web interface, so we can track the build process and monitor logs. In our case, we use the NGINX web server:</p>

<pre><code class="language-bash">$: pkg install nginx
</code></pre>

<h2 id="create-an-ssl-certificate-and-key" id="create-an-ssl-certificate-and-key">Create an SSL certificate and key</h2>

<p>When we build packages with Poudriere, we want to be able to sign them with a private key. This ensures that all of our machines legitimize the packets created and that nobody intercepts the connection to the built computer to send malicious packets.</p>

<p>We&#39;re going to make sure we have an SSL directory that has two subdirectories called keys and certs. We can do this in one command by typing:</p>

<pre><code class="language-bash">$: mkdir -p /usr/local/etc/ssl/{keys,certs}
</code></pre>

<p>Our private key, which must be kept secret, is stored in the key directory. This will be used to sign the packages we are going to create. We can lock the directory so that users without root or sudo privileges cannot interact with the directory or its contents:</p>

<pre><code class="language-bash">$: chmod 0600 /usr/local/etc/ssl/keys
</code></pre>

<p>Next, we create a 4096-bit key, called poudriere.key, and place it in our key&#39;s directory by typing:</p>

<pre><code class="language-bash">$: openssl genrsa -out /usr/local/etc/ssl/keys/poudriere.key 4096
</code></pre>

<p>After the key has been generated, we can create a public certificate from it by typing:</p>

<pre><code class="language-bash">$: openssl rsa -in /usr/local/etc/ssl/keys/poudriere.key -pubout -out /usr/local/etc/ssl/certs/poudriere.cert
</code></pre>

<p>We now have the SSL components we need to sign packets and verify the signatures. Later, we will configure our clients to use the generated certificate for package verification.</p>

<h2 id="configuring-poudriere" id="configuring-poudriere">Configuring Poudriere</h2>

<p>Now that we have our SSL certificate and key, we can start configuring Poudriere.</p>

<p>The main configuration file located at /usr/local/etc/poudriere.conf. We open this file:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/poudriere.conf
</code></pre>

<p>The Poudriere configuration file is very well commented and most of the settings must be predefined. We&#39;ll be making some specific changes, but leaving the majority of them intact.</p>

<p>If we use UFS as the file system, the following option must be commented out:</p>

<pre><code class="language-bash">NO_ZFS=yes
</code></pre>

<p>On the other hand, if our server uses ZFS, we can configure Poudriere to use a specific pool by setting the ZPOOL option. In this pool, we can specify the trunk that Poudriere should use for packets, protocols, etc. with the ZROOTFS option. Note that these two options should not be set when the NO_ZFS option is set to “yes”:</p>

<pre><code class="language-bash"># NO_ZFS=yes
ZPOOL=tank
ZROOTFS=/poudriere
</code></pre>

<p>When building software, Poudriere uses some type of jail to separate the build system from the main operating system. Next, we need to fill in a valid host where the build machine can download the software it needs to do the jails. This is configured via the FREEBSD_HOST option.</p>

<p>This option should already exist, even though it is not currently set to a valid host. We can change this to the default path. ftp://ftp.freebsd.org or use a narrower mirror if we know one:</p>

<pre><code class="language-bash">FREEBSD_HOST=https://download.freebsd.org
</code></pre>

<p>Next, we want to be sure that our data directory is set correctly within the Poudriere root. This is controlled with the POUDRIERE_DATA option and
should be set by default. However, we&#39;ll comment on the option to be certain:</p>

<pre><code class="language-bash">POUDRIERE_DATA=${BASEFS}/data
</code></pre>

<p>The next options that we should comment on are the CHECK<em>CHANGED</em>OPTIONS and CHECK<em>CHANGED</em>DEPS options. The first option tells Poudriere to rebuild packages if the options for them have changed. The second option tells Poudriere to rebuild packages if dependencies have changed since the last compilation.</p>

<p>Both options exist in the form we want in the configuration file. We just have to comment them out:</p>

<pre><code class="language-bash">CHECK_CHANGED_OPTIONS=verbose
CHECK_CHANGED_DEPS=yes
</code></pre>

<p>Next, we&#39;re going to point Poudriere at the SSL key we created so that packages can be signed during the build. The option used to specify is called PKG<em>REPO</em>SIGNING_KEY. We will uncheck this option and change the path to reflect the location of the SSL key we created earlier:</p>

<pre><code class="language-bash">PKG_REPO_SIGNING_KEY=/usr/local/etc/ssl/keys/poudriere.key
</code></pre>

<p>Finally, we can set the URL_BASE string to the domain name or IP address where our server can be reached. This is used by Poudriere to create links in the output that can be clicked. We should include the log and end the value with a slash:</p>

<pre><code class="language-bash">URL_BASE=http://server_domain_or_IP/
</code></pre>

<p>When we&#39;re done making changes, we&#39;ll save and close the file.</p>

<h2 id="create-the-built-environment" id="create-the-built-environment">Create the built environment</h2>

<p>Next, we need to design our built environment. As mentioned earlier, Poudriere will build ports in an isolated environment with jails.</p>

<p>For our purposes, our jails build command looks like this:</p>

<pre><code class="language-bash">$: poudriere jail -c -j 13-0x64 -v 13.0-RELEASE
</code></pre>

<p>This will take a while, so be patient. When done, we can see the one installed by typing:</p>

<pre><code class="language-bash">$: poudriere jail -l
</code></pre>

<p>Output:</p>

<pre><code class="language-bash">JAILNAME        VERSION         ARCH  METHOD TIMESTAMP           PATH

13-0x64 13.0-RELEASE-p2 amd64 ftp    2021-01-06 20:43:48 /usr/local/poudriere/jails/13-0x64
</code></pre>

<p>Once we&#39;ve created a jail, we need to install a port structure.</p>

<p>We can use the -p flag to name our ports tree. We will name our tree HEAD because it summarizes exactly using this tree (the “head” or the most current point of the tree). Likewise, we will update it regularly so that it corresponds to the most current version of the available ports structure:</p>

<pre><code class="language-bash">$: poudriere ports -c -m git+https -B main -p HEAD
</code></pre>

<p>This procedure will also take a while because the entire port structure has to be fetched and extracted. When this is done, we can view our port&#39;s tree by typing:</p>

<pre><code class="language-bash">$: poudriere ports -l
</code></pre>

<p>Now that this step is complete, we have the structures to compile our ports and build packages. Next, we can start by putting together our list of ports to create and configure the options we need for each software.</p>

<h2 id="create-a-port-building-list-and-set-port-options" id="create-a-port-building-list-and-set-port-options">Create a port building list and set port options</h2>

<p>We are going to make a list of ports that we can pass directly to Poudriere.</p>

<p>The file should list the port category followed by a slash and the port name to reflect its position in the ports tree:</p>

<pre><code class="language-bash">port_category/first_port
port_category/second_port
port_category/third_port
</code></pre>

<p>All necessary dependencies are also created automatically. So, we don&#39;t need to track down the entire dependency structure of the ports that we want to install. We can create this file manually, but if our base system already has most of the software installed, we can create the file automatically.</p>

<p>Before we do this, it is usually a good idea to remove any unnecessary dependencies from our system to keep the port list as clean as possible. We can do this by typing:</p>

<pre><code class="language-bash">$: pkg autoremove
</code></pre>

<p>Thereafter, we can get a list of the software that we have explicitly installed on our build system:</p>

<pre><code class="language-bash">$: pkg query -e &#34;%a==0&#34; &#34;%o&#34; | sort -d | tee /usr/local/etc/poudriere.d/port-list
</code></pre>

<p>If there are ports that we don&#39;t want to add, we&#39;ll remove the associated line. This is also an opportunity to add additional ports that we may need.</p>

<p>If we use certain make.conf options to create our ports, we can create a make.conf file for each jail within our /usr/local/etc/poudriere.d directory. For example, we can create a make.conf file for our jail with this name:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/poudriere.d/13-0x64-make.conf
</code></pre>

<p>I prefer to create a global make.conf that is valid for all jails.</p>

<pre><code class="language-bash">$: nano /usr/local/etc/poudriere.d/make.conf
</code></pre>

<p>Inside, we can specify all the options we want to use when creating our ports. For example, if we prefer not to build documentation, samples, native language support, or X11 support, we can specify:</p>

<pre><code class="language-bash">OPTIONS_UNSET+= DOCS NLS X11 EXAMPLES
</code></pre>

<p>We can also specify <a href="https://svnweb.freebsd.org/ports/head/Mk/bsd.default-versions.mk?view=markup" rel="nofollow">Default_Versions</a>. In my case, it looks like this:</p>

<pre><code class="language-bash">DEFAULT_VERSIONS+= mysql=8.0 php=8.0
</code></pre>

<p>In this case, all packages and/or their dependencies are built with the specified version.</p>

<p>Subsequently, we can configure any of our ports that will create files with the options selected.</p>

<p>We can configure anything that has not yet been configured with the options command. We should pass both the port tree we created (with the -p option) and the jail for which we set these options (with the -j option). Not only that, but we also need to provide the list of ports we want to configure with the -f option.</p>

<pre><code class="language-bash">$: poudriere options -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list
</code></pre>

<p>We see a dialog for each of the ports in the list and all dependencies for which no corresponding options are set in the -options directory. The information in our make.conf file is preselected in the selection screens. We&#39;ll select all the options we want to use.</p>

<p>If we want to reconfigure the options for our ports in the future, we can run the above command again with the -c option. This will show us all the available configuration options, regardless of whether we have made a selection in the past:</p>

<pre><code class="language-bash">$: poudriere options -c -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list
</code></pre>

<h2 id="build-the-ports" id="build-the-ports">Build the ports</h2>

<p>Now we&#39;re finally ready to start building ports.</p>

<p>We enter the following to update the jail:</p>

<pre><code class="language-bash">$: poudriere jail -u -j 13-0x64
</code></pre>

<p>Then we enter the following to update the ports structure:</p>

<pre><code class="language-bash">$: poudriere ports -u -p HEAD
</code></pre>

<p>Once that is done, we can start the build process.</p>

<p><strong>Note</strong>: this can be a very long process. If we are connected to the server via SSH, we recommend installing the screen package and starting a session:</p>

<pre><code class="language-bash">$: pkg install screen
$: rehash
$: screen
</code></pre>

<p>To start the build, we just need to use the bulk command and point to all of the individual parts that we have configured. If we&#39;ve used the values in this guide, the command looks like this:</p>

<pre><code class="language-bash">$: poudriere bulk -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list
</code></pre>

<p>This starts with many workers (depending on our poudriere.conf file or the number of CPUs available) and starts building the ports.</p>

<p>At any time during the creation process, we can get information about the progress by holding down the CTRL key and pressing t.</p>

<p>Certain parts of the process produce more output than others.</p>

<h2 id="setting-up-nginx-for-providing-the-front-end-and-the-repository" id="setting-up-nginx-for-providing-the-front-end-and-the-repository">Setting up NGINX  for providing the front end and the repository</h2>

<p>For this step, the NGINX must be set up with virtual hosts.</p>

<p>The following hostname entered /etc/hosts:</p>

<p><code>127.0.0.1 bsd. «Domain»</code></p>

<p>For Poudriere to run under NGINX, the following file created under /usr/local/etc/nginx/vhosts/ under the name poudriere.conf with this content:</p>

<pre><code class="language-bash">server {
  listen 80 default;
  server_name bsd.&gt;&lt;domain&gt;&gt;;
  root /usr/local/share/poudriere/html;

  location /data {
    alias /usr/local/poudriere/data/logs/bulk;
    autoindex on;
  }

  location /packages {
    root /usr/local/poudriere/data;
    autoindex on;
  }
}
</code></pre>

<p>Then restart the NGINX:</p>

<pre><code class="language-bash">$: service nginx restart
</code></pre>

<p>Next, we&#39;re going to make a small change to our mime.types file. If we click on a log in the web browser with the current settings, the file is downloaded and not displayed as normal text. We can change this behavior by marking files with the extension .log. as plain text files.</p>

<p>We open the file mime.types in our text editor:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/nginx/mime.types
</code></pre>

<p>We find the entry indicating the text / plain content type, and append the log to the end of the current list of file types separated by a space:</p>

<pre><code class="language-bash">text/mathml                         mml;
text/plain                          txt log;
text/vnd.sun.j2me.app-descriptor    jad;
</code></pre>

<p>Now, we can display the Poudriere web interface by going to the domain name or the IP address of our server in our web browser, bsd.«domain».</p>

<h2 id="configure-package-clients" id="configure-package-clients">Configure package clients</h2>

<p>Now that we have created packages and configured a repository to host our packages, we can configure our clients to use our server as a package source.</p>

<h3 id="configure-the-build-server-to-use-the-own-package-repo" id="configure-the-build-server-to-use-the-own-package-repo">Configure the build server to use the own package repo</h3>

<p>We can start by configuring the build server to use the packages it built.</p>

<p>First, we need to create a directory for our repository configuration files:</p>

<pre><code class="language-bash">$: mkdir -p /usr/local/etc/pkg/repos
</code></pre>

<p>In this directory, we can create our repository configuration file. It must end in .conf, so we&#39;ll call it poudriere.conf to make its purpose cleaner:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/pkg/repos/poudriere.conf =&gt;

poudriere: {
  url: &#34;file:///usr/local/poudriere/data/packages/13-0x64-HEAD&#34;,
  mirror_type: &#34;srv&#34;,
  signature_type: &#34;pubkey&#34;,
  pubkey: &#34;/usr/local/etc/ssl/certs/poudriere.cert&#34;,
  enabled: yes,
  priority: 100
}
</code></pre>

<p>If we only select packages that we have created ourselves (the more secure option), we can omit the priority setting, but we should disable the default repositories. We can do this by creating another repo file that will overwrite the default repository file and disable it:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/pkg/repos/freebsd.conf =&gt;

FreeBSD: {
  enabled: no
}
</code></pre>

<p>Regardless of our configuration choices, we should now be ready to use our repository. We&#39;ll update our package list by entering:</p>

<pre><code class="language-bash">$: pkg update
</code></pre>

<p>Now, our server can use the pkg command to install packages from our local repository.</p>

<h3 id="configure-remote-clients-to-use-your-build-machine-s-repository" id="configure-remote-clients-to-use-your-build-machine-s-repository">Configure remote clients to use your build machine&#39;s repository</h3>

<p>One of the most compelling reasons to set up Poudriere on a build machine is to use that host as a repository for many other machines. All we have to do to get this working is to download the public SSL certificate from our build machine and set up a similar repository definition.</p>

<p>To connect to our build host from our client computers, we should start an SSH agent on <strong>our local computer</strong> to store our SSH key credentials.</p>

<p>We need to add our SSH key by typing:</p>

<pre><code class="language-bash">$: ssh-add
</code></pre>

<p>Then, we first have to create the directory structure (if it doesn&#39;t exist) so that we can save the certificate. We&#39;ll go ahead and create a directory for keys so we can use it for future tasks:</p>

<pre><code class="language-bash">$: mkdir -p /usr/local/etc/ssl/{keys,certs}
</code></pre>

<p>Now we can connect to our build machine with SSH and send the certificate file back to our client machine. Since we&#39;ve forwarded our SSH credentials, we should be able to do this without asking for a password:</p>

<pre><code class="language-bash">$: ssh user@server_domain_or_IP &#39;cat /usr/local/etc/ssl/certs/poudriere.cert&#39; | tee /usr/local/etc/ssl/certs/poudriere.cert
</code></pre>

<p>This command connects to the build machine from our client computer using our local SSH credentials. As soon as the connection is established, it shows the content of your certificate file and directs us through the SSH tunnel back to our remote client computer. From there, we use the tee combination to write the certificate into our directory.</p>

<p>Once this is done, we can create our repository directory structure, like on the build machine itself:</p>

<pre><code class="language-bash">$: mkdir -p /usr/local/etc/pkg/repos
</code></pre>

<p>Now, we can create a repository file similar to the one used on the build machine:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/pkg/repos/poudriere.conf =&gt;

poudriere: {
  url: &#34;https://server_domain_or_IP/packages/13-0x64-HEAD/&#34;,
  mirror_type: &#34;https&#34;,
  signature_type: &#34;pubkey&#34;,
  pubkey: &#34;/usr/local/etc/ssl/certs/poudriere.cert&#34;,
  enabled: yes,
  priority: 100
}
</code></pre>

<p>If we just want to use our compiled packages, the file should look something like this:</p>

<pre><code class="language-bash">poudriere: {
  url: &#34;https://server_domain_or_IP/packages/13-0x64-HEAD/&#34;,
  mirror_type: &#34;https&#34;,
  signature_type: &#34;pubkey&#34;,
  pubkey: &#34;/usr/local/etc/ssl/certs/poudriere.cert&#34;,
  enabled: yes
}
</code></pre>

<p>If we only want to use our packages, we must remember to create a different repository configuration file to override the default FreeBSD repository configuration:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/pkg/repos/freebsd.conf =&gt;

FreeBSD: {
  enabled: no
}
</code></pre>

<p>After we&#39;re done, let&#39;s update our pkg database to start using our custom compiled packages:</p>

<pre><code class="language-bash">$: pkg update
</code></pre>

<h2 id="cron-job" id="cron-job">Cron job</h2>

<p>So that Poudriere automatically updates the jails and builds the packages, we will set up a cron job.</p>

<p>We create the following file under /usr/local/etc/poudriere.d/scripts:</p>

<pre><code class="language-bash">$: mkdir /usr/local/etc/poudriere.d/scripts

$: nano /usr/local/etc/poudriere.d/scripts/poudriere-cron.sh =&gt;

#!/bin/sh

SCRIPTNAME=`basename &#34;$0&#34;`

# check for running script
STATUS=`ps ax | grep &#34;$SCRIPTNAME&#34; | grep -v grep | wc -l`

# compare to 2 because the ` create a subprocess
if [ &#34;$STATUS&#34; -gt 2 ]; then
  echo &#34;already running ... exit&#34;
  exit 0
fi

# The build
POUDRIERE=&#34;/usr/local/bin/poudriere&#34;
PORTLIST=&#34;/usr/local/etc/poudriere.d/port-list&#34;
JAILS=&#34;13-0x64&#34;
REPOS=&#34;HEAD&#34;
URL=&#34;https://bsd.&lt;&lt;domain&gt;&gt;&#34;

poudriere_build() {
    for JAIL in $JAILS; do
      for REPO in $REPOS; do
        echo &#34;Started $JAIL / $REPO / $SET (&#34;`/bin/date | /usr/bin/tr -d &#39;\n&#39;`&#34;)&#34;
        &#34;$POUDRIERE&#34; bulk -j &#34;$JAIL&#34; -z &#34;$SET&#34; -p &#34;$REPO&#34;  -f &#34;$PORTLIST&#34; &gt; /dev/null
        echo &#34;    Cleaning $REPO (&#34;`/bin/date | /usr/bin/tr -d &#39;\n&#39;`&#34;)&#34;
        &#34;$POUDRIERE&#34; pkgclean -j &#34;$JAIL&#34; -z &#34;$SET&#34; -p &#34;$REPO&#34; -f &#34;$PORTLIST&#34; -y &gt; /dev/null
        echo &#34;    Finished $REPO (&#34;`/bin/date | /usr/bin/tr -d &#39;\n&#39;`&#34;)&#34;
      done
    done
}

repos_update() {
  echo &#34;[$SCRIPTNAME] Updating ports tree...&#34;

  for REPO in $REPOS; do
    echo &#34;[$SCRIPTNAME] Updating ports tree... $REPO&#34;
    &#34;$POUDRIERE&#34; ports -p &#34;$REPO&#34; -u &gt; /dev/null

    if [ $? -ne 0 ]; then
      echo &#34;    Error updating ports tree.&#34;
      exit 1
    fi

  echo &#34;    Ports tree has been updated.&#34;
  done
}

echo &#34;This is a log of poudriere. Details: $URL&#34;
echo &#34;&#34;

repos_update
poudriere_build

echo &#34;[$SCRIPTNAME] Cleaning distfiles...&#34;
&#34;$POUDRIERE&#34; distclean -p &#34;$REPOS&#34; -f &#34;$PORTLIST&#34; -y &gt; /dev/null

echo &#34;[$SCRIPTNAME] Finished. (&#34;`/bin/date | /usr/bin/tr -d &#39;\n&#39;`&#34;)&#34;
exit 0
</code></pre>

<p>Then make it executable:</p>

<pre><code class="language-bash">$: chmod +x /usr/local/etc/poudriere.d/scripts/poudriere-cron.sh
</code></pre>

<p>Then we should run the script once to test whether everything works correctly.</p>

<p>If everything fits, we can include it in the /etc/crontab as follows:</p>

<pre><code class="language-bash">
§: nano /etc/crontab =&gt;

10      0       *       *       *       root    /usr/local/etc/poudriere.d/scripts/poudriere-cron.sh
</code></pre>

<p>The build process will then run every night. If we have packages such as Chromium where the build takes longer than 24 hours, it can be adjusted here.</p>

<h2 id="command-list" id="command-list">Command list</h2>

<h3 id="poudriere-make-conf" id="poudriere-make-conf">Poudriere make.conf</h3>

<pre><code class="language-bash">$: nano /usr/local/etc/poudriere.d/make.conf
</code></pre>

<h3 id="poudriere-conf" id="poudriere-conf">Poudriere conf</h3>

<pre><code class="language-bash">$: nano /usr/local/etc/poudriere.conf
</code></pre>

<h3 id="portlist" id="portlist">Portlist</h3>

<pre><code class="language-bash">$: nano  /usr/local/etc/poudriere.d/port-list
</code></pre>

<h3 id="create-a-new-jail" id="create-a-new-jail">Create a new jail</h3>

<pre><code class="language-bash">$: poudriere jail -c -j 13-0x64 -v 12.0-RELEASE
</code></pre>

<h3 id="update-a-jail" id="update-a-jail">Update a jail</h3>

<pre><code class="language-bash">$: poudriere jail -u -j 13-0x64
</code></pre>

<h3 id="update-ports" id="update-ports">Update ports</h3>

<pre><code class="language-bash">$: poudriere ports -u -p HEAD
</code></pre>

<h3 id="remove-unused-packages" id="remove-unused-packages">Remove unused packages</h3>

<pre><code class="language-bash">$: poudriere pkgclean -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list
</code></pre>

<h3 id="set-options-for-the-port-list" id="set-options-for-the-port-list">Set options for the port list</h3>

<pre><code class="language-bash">$: poudriere options -c -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list
</code></pre>

<h3 id="set-options-for-a-package" id="set-options-for-a-package">Set options for a package</h3>

<pre><code class="language-bash">$: poudriere options -c -j 13-0x64 -p HEAD  databases/mariadb103-client
</code></pre>

<h3 id="build-packages-without-a-cronjob" id="build-packages-without-a-cronjob">Build packages without a cronjob</h3>

<pre><code class="language-bash">$: poudriere bulk -j 13-0x64 -p HEAD -f /usr/local/etc/poudriere.d/port-list
</code></pre>

<h3 id="when-upgrading-the-system-copy-the-options-to-the-new-version" id="when-upgrading-the-system-copy-the-options-to-the-new-version">When upgrading the system, copy the options to the new version</h3>

<pre><code class="language-bash">$: cp -R /usr/local/etc/poudriere.d/12-2x64-HEAD-options/**.* /usr/local/etc/poudriere.d/13-0x64-HEAD-options/
</code></pre>

<p><a href="https://remark.as/p/danschmid/poudriere-guide" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/poudriere-guide</guid>
      <pubDate>Sat, 17 Sep 2022 20:32:26 +0000</pubDate>
    </item>
    <item>
      <title>Install NGINX on FreeBSD</title>
      <link>https://danschmid.writeas.com/install-nginx-on-freebsd?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[Here is a brief description of how the Nginx web server is installed on FreeBSD.&#xA;&#xA;!--more--&#xA;&#xA;NGINX is a powerful edge web server with the lowest memory requirements and the most important functions for building a modern and efficient web infrastructure.&#xA;&#xA;Here is a brief description of how the NGINX web server is installed on FreeBSD.&#xA;&#xA;$: pkg install nginx-full&#xA;$: service nginx enable&#xA;$: service nginx start&#xA;&#xA;Next, the following directory is created where the virtual host&#39;s files are saved.&#xA;&#xA;$: mkdir /usr/local/etc/nginx/vhosts/&#xA;&#xA;For the vhost to be integrated, we have to add this line to our nginx.conf  at the end of the http block:&#xA;&#xA;$: nano /usr/local/etc/nginx/nginx.conf =  &#34;include /usr/local/etc/nginx/vhosts/&#34;;&#xA;&#xA;GZIP compression&#xA;&#xA;GZIP compression allows us to shrink files, reducing the time it takes to transfer a resource from the server to a browser. In today&#39;s web environment, many browsers and servers support GZIP compression. The ability to reduce the file size by up to 70% is a great incentive to use this compression method. Enabling GZIP compression is considered a high-priority recommendation by the website speed test tools because, without this option, we will unnecessarily increase the loading time of our website.&#xA;&#xA;To enable GZIP compression, we will edit the file /usr/local/etc/nginx/nginx.conf and add the following to the server block:&#xA;&#xA;gzip on;&#xA;gzipdisable &#34;msie6&#34;;&#xA;gzipvary on;&#xA;gzipproxied any;&#xA;gzipcomplevel 6;&#xA;gzipbuffers 16 8k;&#xA;gziphttpversion 1.1;&#xA;gziptypes application/javascript application/rss+xml application/vnd.ms-fontobject application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/opentype font/otf font/ttf image/svg+xml image/x-icon text/css text/javascript text/plain text/xml;&#xA;&#xA;Then we restart NGINX: service nginx restart&#xA;&#xA;We can test with curl whether the compression method works:&#xA;&#xA;$: curl -H &#39;Accept-Encoding: gzip&#39; -I https://webseite =  HTTP/1.1 200 OK&#xA;Server: nginx/1.16.0&#xA;Date: Sun, 18 Aug 2019 19:38:45 GMT&#xA;Content-Type: text/html; charset=utf-8&#xA;Last-Modified: Sun, 18 Aug 2019 18:27:06 GMT&#xA;Connection: keep-alive&#xA;ETag: W/&#34;5d59987a-39e7&#34;&#xA;Content-Encoding: gzip&#xA;&#xA;Brotli compression&#xA;&#xA;Brotli compression is a new open-source compression algorithm developed by Google to further reduce file size. In 2013, Google released another compression algorithm called Zopli to perform “perfect but slow deflate or Zlib compression”. Based on a compression algorithm study carried out at Google, Brotli could achieve significantly faster performance with a compression rate that was 20 to 26% higher than Zopli.&#xA;&#xA;To activate the Brotli compression, we will edit the file /usr/local/etc/nginx/nginx.conf and add the following in the server block:&#xA;&#xA;brotli on;&#xA;brotlicomplevel 6;&#xA;brotlistatic on;&#xA;brotlitypes text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/vnd.microsoft.icon image/bmp image/svg+xml;&#xA;&#xA;And at the beginning of the configuration file:&#xA;&#xA;loadmodule  /usr/local/libexec/nginx/ngxhttpbrotlifiltermodule.so;&#xA;loadmodule  /usr/local/libexec/nginx/ngxhttpbrotlistatic_module.so;&#xA;&#xA;Then we restart NGINX: service nginx restart&#xA;&#xA;We can test with curl whether the compression method works:&#xA;&#xA;$: curl -H &#39;Accept-Encoding: br&#39; -I https://webseite =  HTTP/1.1 200 OK&#xA;Server: nginx/1.16.0&#xA;Date: Sun, 18 Aug 2019 19:38:45 GMT&#xA;Content-Type: text/html; charset=utf-8&#xA;Last-Modified: Sun, 18 Aug 2019 18:27:06 GMT&#xA;Connection: keep-alive&#xA;ETag: W/&#34;5d59987a-39e7&#34;&#xA;Content-Encoding: br&#xA;&#xA;Certbot&#xA;&#xA;To create SSL certificates from Let&#39;s encrypt and automatically provide them for NGINX, we will use the two packages py-certbot and py-certbot-nginx with the following command:&#xA;&#xA;$: pkg install py39-certbot py39-certbot-nginx&#xA;&#xA;Then, with the command, certbot SSL certificates can automatically be created for all domains that are created in, etc/hosts. With the instruction certbot renew, the expired certificates can be automatically updated.&#xA;&#xA;Every night, cronjob checks whether the certificates are up-to-date or whether they need to be renewed. The following entered the /etc/crontab:&#xA;&#xA;30      23                           root    certbot renew&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/install-nginx-on-freebsd&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>Here is a brief description of how the Nginx web server is installed on FreeBSD.</p>



<p>NGINX is a powerful edge web server with the lowest memory requirements and the most important functions for building a modern and efficient web infrastructure.</p>

<p>Here is a brief description of how the <a href="https://www.freshports.org/www/nginx-full" rel="nofollow">NGINX</a> web server is installed on FreeBSD.</p>

<pre><code class="language-bash">$: pkg install nginx-full
$: service nginx enable
$: service nginx start
</code></pre>

<p>Next, the following directory is created where the virtual host&#39;s files are saved.</p>

<pre><code class="language-bash">$: mkdir /usr/local/etc/nginx/vhosts/
</code></pre>

<p>For the vhost to be integrated, we have to add this line to our nginx.conf  at the end of the http block:</p>

<pre><code class="language-bash">$: nano /usr/local/etc/nginx/nginx.conf =&gt;

&#34;include /usr/local/etc/nginx/vhosts/*&#34;;
</code></pre>

<h2 id="gzip-compression" id="gzip-compression">GZIP compression</h2>

<p>GZIP compression allows us to shrink files, reducing the time it takes to transfer a resource from the server to a browser. In today&#39;s web environment, many browsers and servers support GZIP compression. The ability to reduce the file size by up to 70% is a great incentive to use this compression method. Enabling GZIP compression is considered a high-priority recommendation by the website speed test tools because, without this option, we will unnecessarily increase the loading time of our website.</p>

<p>To enable GZIP compression, we will edit the file /usr/local/etc/nginx/nginx.conf and add the following to the server block:</p>

<pre><code class="language-bash">gzip on;
gzip_disable &#34;msie6&#34;;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types application/javascript application/rss+xml application/vnd.ms-fontobject application/x-font application/x-font-opentype application/x-font-otf application/x-font-truetype application/x-font-ttf application/x-javascript application/xhtml+xml application/xml font/opentype font/otf font/ttf image/svg+xml image/x-icon text/css text/javascript text/plain text/xml;
</code></pre>

<p>Then we restart NGINX: service nginx restart</p>

<p>We can test with curl whether the compression method works:</p>

<pre><code class="language-bash">$: curl -H &#39;Accept-Encoding: gzip&#39; -I https://&lt;webseite&gt; =&gt; 

HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Sun, 18 Aug 2019 19:38:45 GMT
Content-Type: text/html; charset=utf-8
Last-Modified: Sun, 18 Aug 2019 18:27:06 GMT
Connection: keep-alive
ETag: W/&#34;5d59987a-39e7&#34;
Content-Encoding: gzip
</code></pre>

<h2 id="brotli-compression" id="brotli-compression">Brotli compression</h2>

<p>Brotli compression is a new open-source compression algorithm developed by Google to further reduce file size. In 2013, Google released another compression algorithm called Zopli to perform “perfect but slow deflate or Zlib compression”. Based on a compression algorithm study carried out at Google, Brotli could achieve significantly faster performance with a compression rate that was 20 to 26% higher than Zopli.</p>

<p>To activate the Brotli compression, we will edit the file /usr/local/etc/nginx/nginx.conf and add the following in the server block:</p>

<pre><code class="language-bash">brotli on;
brotli_comp_level 6;
brotli_static on;
brotli_types text/plain text/css application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript image/x-icon image/vnd.microsoft.icon image/bmp image/svg+xml;
</code></pre>

<p>And at the beginning of the configuration file:</p>

<pre><code class="language-bash">load_module  /usr/local/libexec/nginx/ngx_http_brotli_filter_module.so;
load_module  /usr/local/libexec/nginx/ngx_http_brotli_static_module.so;
</code></pre>

<p>Then we restart NGINX: service nginx restart</p>

<p>We can test with curl whether the compression method works:</p>

<pre><code class="language-bash">$: curl -H &#39;Accept-Encoding: br&#39; -I https://&lt;webseite&gt; =&gt; 

HTTP/1.1 200 OK
Server: nginx/1.16.0
Date: Sun, 18 Aug 2019 19:38:45 GMT
Content-Type: text/html; charset=utf-8
Last-Modified: Sun, 18 Aug 2019 18:27:06 GMT
Connection: keep-alive
ETag: W/&#34;5d59987a-39e7&#34;
Content-Encoding: br
</code></pre>

<h2 id="certbot" id="certbot">Certbot</h2>

<p>To create SSL certificates from Let&#39;s encrypt and automatically provide them for NGINX, we will use the two packages <a href="https://www.freshports.org/security/py-certbot" rel="nofollow">py-certbot</a> and <a href="https://www.freshports.org/security/py-certbot-nginx" rel="nofollow">py-certbot-nginx</a> with the following command:</p>

<pre><code class="language-bash">$: pkg install py39-certbot py39-certbot-nginx
</code></pre>

<p>Then, with the command, certbot SSL certificates can automatically be created for all domains that are created in, etc/hosts. With the instruction certbot renew, the expired certificates can be automatically updated.</p>

<p>Every night, cronjob checks whether the certificates are up-to-date or whether they need to be renewed. The following entered the <code>/etc/crontab</code>:</p>

<pre><code class="language-bash">30      23      *       *       *       root    certbot renew
</code></pre>

<p><a href="https://remark.as/p/danschmid/install-nginx-on-freebsd" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/install-nginx-on-freebsd</guid>
      <pubDate>Sat, 17 Sep 2022 20:22:30 +0000</pubDate>
    </item>
    <item>
      <title>Dark themes for GTK and QT5 applications</title>
      <link>https://danschmid.writeas.com/dark-themes-for-gtk-and-qt5-applications?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In this tutorial, I will explain how to install a nice dark theme.&#xA;&#xA;!--more--&#xA;&#xA;QT5 and GTK are used to create the graphical user interface for applications. They each have their appearance, depending on the theme and symbols installed.&#xA;&#xA;So installing a dark GTK theme doesn&#39;t change the look of QT5 applications like VLC and QBittorrent.&#xA;&#xA;To create a more consistent look and feel for applications, we&#39;d like both gtk and qt5 to use a dark theme.&#xA;&#xA;We installed the package gtk-arc-themes, which contains the theme adwaita-dark, and the packages&#xA;lxappearance to set the dark theme for GTK applications.&#xA;&#xA;$: doas pkg install gtk-arc-themes lxappearance&#xA;&#xA;We open now lxappearance and we can choose the arc-dark here.&#xA;&#xA;Next, we need the ports&#xA;&#xA;adwaita-qt5&#xA;qt5-style-plugins&#xA;qt5ct&#xA;&#xA;$: doas pkg install adwaita-qt5 qt5-style-plugins qt5ct&#xA;&#xA;Install and activate the dark theme for qt5-based applications.&#xA;&#xA;We then add the following code to our .xinitrc-this is needed for the qt5ct program which we can use to configure which theme qt5 applications use.&#xA;&#xA;$: nano ~/.xinitrc =  export QTQPAPLATFORMTHEME=qt5ct&#xA;&#xA;Now we need to restart the computer. If we open the qt5ct program before restarting, the variable will not be recorded, and we will not be able to change the subject.&#xA;&#xA;After the restart, we open the qt5ct program and change the design to the qt5 version of adwaita-dark.&#xA;&#xA;We can open the qt5ct program with an application launcher like dmenu or rofi when you use it.&#xA;&#xA;We&#39;ll use the Appearance tab, the drop-down menu, next to the word style. Likewise, we&#39;ll select Adwaita-Dark, then click Apply.&#xA;&#xA;Let&#39;s go to the Fonts, tab and we&#39;ll change the font to Sans Serif 10. We click Apply and OK to close qt5ct.&#xA;&#xA;Now, when we open qt5-based applications like vlc and qbittorrent, the Adwaita Dark theme is used just like gtk applications.&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/dark-themes-for-gtk-and-qt5-applications&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>In this tutorial, I will explain how to install a nice dark theme.</p>



<p>QT5 and GTK are used to create the graphical user interface for applications. They each have their appearance, depending on the theme and symbols installed.</p>

<p>So installing a dark GTK theme doesn&#39;t change the look of QT5 applications like VLC and QBittorrent.</p>

<p>To create a more consistent look and feel for applications, we&#39;d like both gtk and qt5 to use a dark theme.</p>

<p>We installed the package <a href="https://www.freshports.org/x11-themes/gtk-arc-themes" rel="nofollow">gtk-arc-themes</a>, which contains the theme adwaita-dark, and the packages
<a href="https://www.freshports.org/x11-themes/lxappearance/" rel="nofollow">lxappearance</a> to set the dark theme for GTK applications.</p>

<pre><code class="language-bash">$: doas pkg install gtk-arc-themes lxappearance
</code></pre>

<p>We open now lxappearance and we can choose the arc-dark here.</p>

<p><img src="https://i.snap.as/tZdxWBth.png" alt=""/></p>

<p>Next, we need the ports</p>
<ul><li><a href="https://www.freshports.org/x11-themes/adwaita-qt5" rel="nofollow">adwaita-qt5</a></li>
<li><a href="https://www.freshports.org/x11-themes/qt5-style-plugins" rel="nofollow">qt5-style-plugins</a></li>
<li><a href="https://www.freshports.org/misc/qt5ct" rel="nofollow">qt5ct</a></li></ul>

<pre><code class="language-bash">$: doas pkg install adwaita-qt5 qt5-style-plugins qt5ct
</code></pre>

<p>Install and activate the dark theme for qt5-based applications.</p>

<p>We then add the following code to our .xinitrc-this is needed for the qt5ct program which we can use to configure which theme qt5 applications use.</p>

<pre><code class="language-bash">$: nano ~/.xinitrc =&gt;

export QT_QPA_PLATFORMTHEME=qt5ct
</code></pre>

<p>Now we need to restart the computer. If we open the qt5ct program before restarting, the variable will not be recorded, and we will not be able to change the subject.</p>

<p>After the restart, we open the qt5ct program and change the design to the qt5 version of adwaita-dark.</p>

<p>We can open the qt5ct program with an application launcher like dmenu or rofi when you use it.</p>

<p>We&#39;ll use the Appearance tab, the drop-down menu, next to the word style. Likewise, we&#39;ll select Adwaita-Dark, then click Apply.</p>

<p><img src="https://i.snap.as/WtC73gIn.png" alt=""/></p>

<p>Let&#39;s go to the Fonts, tab and we&#39;ll change the font to Sans Serif 10. We click Apply and OK to close qt5ct.</p>

<p><img src="https://i.snap.as/bu4Jqf7J.png" alt=""/></p>

<p>Now, when we open qt5-based applications like vlc and qbittorrent, the Adwaita Dark theme is used just like gtk applications.</p>

<p><img src="https://i.snap.as/qIdxKBlZ.png" alt=""/></p>

<p><a href="https://remark.as/p/danschmid/dark-themes-for-gtk-and-qt5-applications" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/dark-themes-for-gtk-and-qt5-applications</guid>
      <pubDate>Sat, 17 Sep 2022 19:38:57 +0000</pubDate>
    </item>
    <item>
      <title>Setup KeepassXC under FreeBSD</title>
      <link>https://danschmid.writeas.com/setup-keepassxc-under-freebsd?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In this Tutorial, I show you how you can install KeepassXC under FreeBSD.&#xA;&#xA;!--more--&#xA;&#xA;KeepassXC is a community branch of KeePassXC—a native cross-platform port of KeePass Password Safe to add new features and improve it and bug fixes for a feature-rich, cross-platform and modern feature rich Open-source password manager.&#xA;&#xA;Main features:&#xA;&#xA;Secure storage with AES, Twofish, or ChaCha20 encryption&#xA;File format compatibility with KeePass2, KeePassX, MacPass, KeeWeb, and many others (KDBX 3.1 and 4.0)&#xA;SSH agent integration&#xA;Sync passwords with KeeShare&#xA;Auto-Type to automatically fill out registration forms&#xA;Support for key files and YubiKey-Challenge-Response for additional security&#xA;TOTP generation (including Steam Guard)&#xA;CSV import from other password managers (e.g., LastPass)&#xA;Command-line interface&#xA;Custom icons for database entries and downloading website favorites&#xA;Functionality to merge databases&#xA;Automatic reload of the database has changed externally&#xA;Browser integration with KeePassXC browser for Google Chrome, Chromium, Vivaldi, and Mozilla Firefox.&#xA;&#xA;Install KeepassXC&#xA;&#xA;$: doas pkg install keepassxc&#xA;&#xA;How do I use KeepassXC&#xA;&#xA;I will briefly show you how to set up KeepassXC and how to use it.&#xA;When we start KeepassXc for the first time, we see the main screen.&#xA;&#xA;Then we will create a new database. A new screen opens, and we can assign a database name here and optionally assign a description.&#xA;&#xA;On the next screen, we can make encryption settings. Here we can, for example, set the encryption time and select the database format.&#xA;&#xA;We can also make advanced settings. For example, we can make the following settings here:&#xA;&#xA;encryption algorithm&#xA;Key derivation function&#xA;Encryption passes&#xA;memory usage&#xA;&#xA;In the next step, we can now assign a password, with which the password database is encrypted. What I can recommend is to also create a key file which is then saved on an external USB stick or in an encrypted cloud service. This means that the database backed up twice.&#xA;&#xA;We have now created an encrypted database so that we can use KeepassXC; with Firefox, we must first activate the browser integration in the KeepassXC settings. We then select Firefox and can then set additional settings. I leave that to you, which you want to set.&#xA;&#xA;For the actual integration, we use the KeeepassXC-Browser extension.&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/setup-keepassxc-under-freebsd&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>In this Tutorial, I show you how you can install KeepassXC under FreeBSD.</p>



<p><a href="https://www.freshports.org/security/keepassxc/" rel="nofollow">KeepassXC</a> is a community branch of KeePassXC—a native cross-platform port of KeePass Password Safe to add new features and improve it and bug fixes for a feature-rich, cross-platform and modern feature rich Open-source password manager.</p>

<p>Main features:</p>
<ul><li>Secure storage with AES, Twofish, or ChaCha20 encryption</li>
<li>File format compatibility with KeePass2, KeePassX, MacPass, KeeWeb, and many others (KDBX 3.1 and 4.0)</li>
<li>SSH agent integration</li>
<li>Sync passwords with KeeShare</li>
<li>Auto-Type to automatically fill out registration forms</li>
<li>Support for key files and YubiKey-Challenge-Response for additional security</li>
<li>TOTP generation (including Steam Guard)</li>
<li>CSV import from other password managers (e.g., LastPass)</li>
<li>Command-line interface</li>
<li>Custom icons for database entries and downloading website favorites</li>
<li>Functionality to merge databases</li>
<li>Automatic reload of the database has changed externally</li>
<li>Browser integration with KeePassXC browser for Google Chrome, Chromium, Vivaldi, and Mozilla Firefox.</li></ul>

<h2 id="install-keepassxc" id="install-keepassxc">Install KeepassXC</h2>

<pre><code class="language-bash">$: doas pkg install keepassxc
</code></pre>

<h2 id="how-do-i-use-keepassxc" id="how-do-i-use-keepassxc">How do I use KeepassXC</h2>

<p>I will briefly show you how to set up KeepassXC and how to use it.
When we start KeepassXc for the first time, we see the main screen.</p>

<p><img src="https://i.snap.as/rKYv0QRX.png" alt=""/></p>

<p>Then we will create a new database. A new screen opens, and we can assign a database name here and optionally assign a description.</p>

<p><img src="https://i.snap.as/6FMV9RUm.png" alt=""/></p>

<p>On the next screen, we can make encryption settings. Here we can, for example, set the encryption time and select the database format.</p>

<p><img src="https://i.snap.as/7JCU4wzI.png" alt=""/></p>

<p>We can also make advanced settings. For example, we can make the following settings here:</p>
<ul><li>encryption algorithm</li>
<li>Key derivation function</li>
<li>Encryption passes</li>
<li>memory usage</li></ul>

<p><img src="https://i.snap.as/ZlhVNGgt.png" alt=""/></p>

<p>In the next step, we can now assign a password, with which the password database is encrypted. What I can recommend is to also create a key file which is then saved on an external USB stick or in an encrypted cloud service. This means that the database backed up twice.</p>

<p><img src="https://i.snap.as/q2R0V4D2.png" alt=""/></p>

<p>We have now created an encrypted database so that we can use KeepassXC; with Firefox, we must first activate the browser integration in the KeepassXC settings. We then select Firefox and can then set additional settings. I leave that to you, which you want to set.</p>

<p><img src="https://i.snap.as/HBSwWpQ8.png" alt=""/></p>

<p>For the actual integration, we use the <a href="https://addons.mozilla.org/de/firefox/addon/keepassxc-browser/" rel="nofollow">KeeepassXC-Browser</a> extension.</p>

<p><a href="https://remark.as/p/danschmid/setup-keepassxc-under-freebsd" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/setup-keepassxc-under-freebsd</guid>
      <pubDate>Sat, 17 Sep 2022 19:13:50 +0000</pubDate>
    </item>
    <item>
      <title>Install Firefox under FreeBSD and set it up with privacy</title>
      <link>https://danschmid.writeas.com/install-firefox-under-freebsd-and-set-it-up-with-privacy?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[In this tutorial, I explain how to install the Firefox browser under FreeBSD and also set it up with privacy.&#xA;&#xA;!--more--&#xA;&#xA;Mozilla Firefox is a free, open-source web browser. It&#39;s small, fast, and easy to use, and has many advanced features:&#xA;&#xA;Pop-up blockers&#xA;extensions&#xA;customizable appearance&#xA;improved security&#xA;&#xA;We can installthe Firefox browser with the following command:&#xA;&#xA;$: doas pkg install firefox&#xA;&#xA;Improve privacy&#xA;&#xA;The Firefox browser is inherently privacy-conscious. But I&#39;ll show you how to get even more security and privacy out of Firefox.&#xA;&#xA;about:preferences&#xA;&#xA;First, we enter “about:preferences” in the address line, and this brings us to the settings.&#xA;&#xA;Generally&#xA;&#xA;In the general settings, we will deactivate the following options:&#xA;&#xA;Recommend extensions while browsing&#xA;Recommend functions while browsing&#xA;&#xA;Home&#xA;&#xA;Here, we will disable the following options:&#xA;&#xA;Important pages&#xA;Recommended by Pocket&#xA;overview&#xA;Brief information&#xA;&#xA;search&#xA;&#xA;We will remove all existing search engines and use Searx as the only standard search engine.&#xA;&#xA;But what is SearXNG? It is a free metasearch engine that protects users&#39; privacy. To complete this, Searx does not share users&#39; IP addresses or search history with the search engines from which it collects results. Here; you can find more information about SearXNG.&#xA;&#xA;To add Searx as a search engine, we search here, an instance that we want to use and open it.&#xA;&#xA;Then, we click with the right click in the address bar, and we select the Add Search Engine option from the menu.&#xA;&#xA;Now, we can set SearXNG as the default search engine in the search settings.&#xA;&#xA;Another great alternative are:&#xA;&#xA;Qwant is a search engine with no user tracking and no filter bubble&#xA;Startpage is a search engine that provides Google search results with complete privacy protection&#xA;&#xA;Privacy&#xA;&#xA;Under the item improved protection against activity tracking, we will select the Custom option and set the following settings.&#xA;&#xA;Cookies: all third-party cookies (some websites may no longer work)&#xA;Activity tracking content: in all windows&#xA;Secret digital currency calculator (crypto miner)&#xA;Identifier (fingerprint)&#xA;&#xA;When websites send “Do Not Track” information that their activities should not be tracked, we always set this option.&#xA;&#xA;Under Cookies and website data, we will activate the following:&#xA;&#xA;Delete cookies and website data when you quit Firefox&#xA;&#xA;In the next step, we will deactivate the option to save access data and passwords.&#xA;&#xA;And finally, we will deactivate the following options under Data collection by Firefox and its use:&#xA;&#xA;Allow Firefox to send data on technical details and interactions to Mozilla&#xA;Allow personalized extension recommendations through Firefox&#xA;Allow Firefox to install and run studies&#xA;&#xA;about:config&#xA;&#xA;Next, we go to the about:config page, then we can set further security-relevant options.&#xA;&#xA;We type “about:config” in the Firefox address bar and press Enter. Then we press the “Accept risk and continue” button.&#xA;&#xA;To change settings here, we copy the following settings (e.g., “webgl.disabled”), paste them into the search bar and set them to the specified value (e.g., “true”).&#xA;&#xA;Disable telemetry&#xA;&#xA;With the following changes, we will disable the Firefox telemetry:&#xA;&#xA;browser.newtabpage.activity-stream.feeds.telemetry = false&#xA;browser.ping-centre.telemetry = false&#xA;browser.tabs.crashReporting.sendReport = false&#xA;devtools.onboarding.telemetry.logged = false&#xA;toolkit.telemetry.enabled = false&#xA;Delete the URL for toolkit.telemetry.server, and leave it empty&#xA;toolkit.telemetry.unified = false&#xA;&#xA;Disable Pocket&#xA;&#xA;If we don&#39;t use Pocket, or we don&#39;t want Firefox&#39;s Pocket integration, make the following changes:&#xA;&#xA;browser.newtabpage.activity-stream.section.highlights.includePocket = false&#xA;extensions.pocket.enabled = false&#xA;&#xA;Disable JavaScript in PDF&#xA;&#xA;While there are legitimate uses for JavaScript in PDF (such as form validation), such uses are not very common. In addition, it could be used for malicious purposes, so it&#39;s generally a good idea to disable this feature.&#xA;&#xA;pdfjs.enableScripting = false.&#xA;&#xA;security.ssl.requiresafenegotiation = true&#xA;&#xA;Making these changes will disable insecure SSL ciphers and force safe negotiation:&#xA;&#xA;privacy.trackingprotection.fingerprinting.enabled = true&#xA;&#xA;This option has been available since Firefox version 67, and it blocks fingerprinting.&#xA;&#xA;privacy.trackingprotection.cryptomining.enabled = true&#xA;&#xA;This option has been available since Firefox version 67 and this blocks CryptoMining.&#xA;&#xA;privacy.trackingprotection.enabled = true&#xA;&#xA;This is Mozilla&#39;s new built-in tracking protection. One of the benefits is to block tracking (i.e., Google Analytics) on privileged pages that have add-ons that normally do this disabled.&#xA;&#xA;Privileged pages are those web pages that browser developers consider legitimate web pages, on which extensions tasked not to work / whose functionality has been completely stopped.&#xA;&#xA;In Firefox, for example:&#xA;&#xA;accounts-static.cdn.mozilla.net&#xA;accounts.firefox.com&#xA;addons.cdn.mozilla.net&#xA;addons.mozilla.org&#xA;api.accounts.firefox.com&#xA;content.cdn.mozilla.net&#xA;content.cdn.mozilla.net&#xA;discovery.addons.mozilla.org&#xA;input.mozilla.org&#xA;install.mozilla.org&#xA;oauth.accounts.firefox.com&#xA;profile.accounts.firefox.com&#xA;support.mozilla.org&#xA;sync.services.mozilla.com&#xA;testpilot.firefox.com&#xA;&#xA;browser.sendpings = false&#xA;&#xA;The attribute is useful for websites to keep track of visitor clicks.&#xA;&#xA;browser.urlbar.speculativeConnect.enabled = false&#xA;&#xA;By doing this, we disable the preloading of autocomplete URLs. Firefox preloads URLs that are autocomplete when a user types in the address bar. This is a problem when suggesting URLs that we don&#39;t want to connect too.&#xA;&#xA;dom.event.clipboardevents.enabled = false&#xA;&#xA;We disable that websites can receive notifications when we copy, paste or cut something from a website. This will tell you which part of the page has selected.&#xA;&#xA;media.eme.enabled = false&#xA;&#xA;Disables playback of DRM-controlled HTML5 content. When this option enabled, the Widevine Content Decryption Module provided by Google Inc. will be downloaded automatically.&#xA;&#xA;media.navigator.enabled = false&#xA;&#xA;Websites can track the microphone and camera status of our device.&#xA;&#xA;network.cookie.cookieBehavior = 1&#xA;&#xA;Disable cookies&#xA;&#xA;0 = Accept all cookies by default&#xA;1 = only accept from the original website (block third-party cookies)&#xA;2 = Block all cookies by default&#xA;&#xA;network.http.referer.XOriginPolicy = 2&#xA;&#xA;We only send the referer header if the full host names match. (Note: if we notice a significant fraction, we can try 1 with a XOriginTrimmingPolicy optimization below.)&#xA;&#xA;0 = send referrer in all cases&#xA;1 = send referrer to the same eTLD sites&#xA;2 = only send referrer if full host names match&#xA;&#xA;network.http.referer.XOriginTrimmingPolicy = 2&#xA;&#xA;When we send the referrer across origins, we only send the schema, host, and port in the referer header of cross origins requests.&#xA;&#xA;0 = send complete URL in the referrer&#xA;1 = send URL without query string in referrer&#xA;2 = Send only the scheme, host, and port in the referrer&#xA;&#xA;webgl.disabled = true&#xA;&#xA;WebGL is a potential security risk.&#xA;&#xA;browser.sessionstore.privacylevel = 2&#xA;&#xA;This setting controls when to save additional information about a session: form, content, scrollbar positions, cookies, and POST data.&#xA;&#xA;0 = save additional session data for any site. (Standard from Firefox 4.)&#xA;1 = save additional session data only for unencrypted (not HTTPS) sites. (Default before Firefox 4.)&#xA;2 = never save additional session data.&#xA;&#xA;beacon.enabled = false&#xA;&#xA;Disabled sending additional analysis to web servers.&#xA;&#xA;browser.safebrowsing.downloads.remote.enabled = false&#xA;&#xA;Prevents Firefox from sending information about downloaded executables to Google Safe Browsing to see if they should be blocked for security reasons.&#xA;&#xA;We&#39;re turning off the Firefox prefetch pages, which we expect to visit next:&#xA;&#xA;Even though prefetching may speed things up a bit, it may connect to servers without user intervention (which can be a privacy issue) and its performance benefits are minimal. Making these changes will disable prefetching:&#xA;&#xA;network.dns.disablePrefetch = true&#xA;network.dns.disablePrefetchFromHTTPS = true&#xA;network.predictor.enabled = false&#xA;network.predictor.enable-prefetch = false&#xA;network.prefetch-next = false&#xA;&#xA;network.IDNshowpunycode = true&#xA;&#xA;Unless we render IDNs as punycode equivalent, we are open to phishing attacks, which are very difficult to detect.&#xA;&#xA;extensions.pocket.enabled = false&#xA;&#xA;This deactivates the Pocket Service.&#xA;&#xA;identity.fxaccounts.enabled = false&#xA;&#xA;We will disable the Firefox Sync Service. I will introduce you to better alternatives. We could also use a self-hosted sync server—the code is available on&#xA;GitHub. But the service is currently still using outdated Python 2.7 code, and the service has ported to Rust meanwhile. And the other problem is that the self-hosted service does not currently work with mobile Firefox.&#xA;&#xA;identity.fxaccounts.toolbar.enabled = false&#xA;&#xA;We&#39;re removing the Firefox Accounts icon from the toolbar.&#xA;&#xA;disable WebRTC&#xA;&#xA;WebRTC can potentially expose your real IP address, changing the following disables it&#xA;&#xA;We can change the following value to be sure that every WebRTC-related are really disabled.&#xA;&#xA;media.peerconnection.turn.disable = true&#xA;media.peerconnection.usedocumenticeservers = false&#xA;media.peerconnection.video.enabled = false&#xA;media.peerconnection.identity.timeout = 1&#xA;&#xA;Hint: This will break any site that uses real-time audio/video communication, which includes almost all real-time chat and conferencing apps.&#xA;&#xA;Add-ons&#xA;&#xA;In this section, I would like to introduce you to a few useful add-ons for Firefox.&#xA;&#xA;uBlock Origin&#xA;&#xA;An efficient blocker: low memory footprint and low CPU load, yet thousands more filters applied than other popular blockers.&#xA;&#xA;xBrowserSync&#xA;&#xA;xBrowserSync synchronizes bookmarks between devices and browsers with end-to-end encryption. Data encrypted and decrypted on the device—nobody but us can read it. No registrationrequired. We just enter a randomly generated ID or QR code on all of our devices. There are different servers available, which can also be self-hosted.&#xA;&#xA;CanvasBlocker&#xA;&#xA;This add-on enables us to prevent websites from identifying us via Javascript APIs. We can choose whether the APIs completely blocked on certain or all pages (this will impair the functionality of some pages) or to fake wrong values for the identification-friendly readout functions.&#xA;&#xA;Chameleon&#xA;&#xA;With this add-on, we falsify our browser profile. It includes some privacy enhancement options.&#xA;&#xA;LocalCDN&#xA;&#xA;This add-on emulates external frameworks (e.g., jQuery, Bootstrap, AngularJS) and makes them available as a local resource. It prevents unnecessary third-party requests like Google, StackPath, MaxCDN, and more. It contains prepared rules for uBlock Origin / uMatrix.&#xA;&#xA;Redirect AMP to HTML&#xA;&#xA;Automatically redirects all AMP (Accelerated Mobile Page) pages to their regular HTML equivalent.&#xA;&#xA;When we see an AMP page, we are likely seeing a page served directly by Bing or Google that can pull up information about what we&#39;re doing on that page. We keep the web decentralized, and we say, “No!” to search engines that want to take control of the web.&#xA;&#xA;AMP pages designed for devices with a small screen and often do not translate well to larger screens. The extension can be especially useful&#xA;when we receive links from people who are on their mobile devices while we are on our desktop computer.&#xA;&#xA;AdBlocker for YouTube&#xA;&#xA;This add-on removes all annoying ads from YouTube.&#xA;&#xA;Important functions:&#xA;&#xA;Removes video and display ads from YouTube&#xA;Loads the YouTube website and videos faster&#xA;Supports both Firefox desktop and mobile (Android)&#xA;&#xA;YouTube NonStop&#xA;&#xA;Tired of seeing the “Video paused. Continue watching?” Confirmation dialog? This extension will automatically click it, so you can listen to your favorite music without interruption.&#xA;&#xA;The add-on works with YouTube and YouTube Music!&#xA;&#xA;a href=&#34;https://remark.as/p/danschmid/install-firefox-under-freebsd-and-set-it-up-with-privacy&#34;Discuss.../a &#xD;&#xA;&#xD;&#xA;!--emailsub--]]&gt;</description>
      <content:encoded><![CDATA[<p>In this tutorial, I explain how to install the Firefox browser under FreeBSD and also set it up with privacy.</p>



<p>Mozilla <a href="https://www.freshports.org/www/firefox" rel="nofollow">Firefox</a> is a free, open-source web browser. It&#39;s small, fast, and easy to use, and has many advanced features:</p>
<ul><li>Pop-up blockers</li>
<li>extensions</li>
<li>customizable appearance</li>
<li>improved security</li></ul>

<p>We can installthe Firefox browser with the following command:</p>

<pre><code>$: doas pkg install firefox
</code></pre>

<p><img src="https://i.snap.as/rqIdUuVZ.png" alt=""/></p>

<h2 id="improve-privacy" id="improve-privacy">Improve privacy</h2>

<p>The Firefox browser is inherently privacy-conscious. But I&#39;ll show you how to get even more security and privacy out of Firefox.</p>

<h3 id="about-preferences" id="about-preferences">about:preferences</h3>

<p>First, we enter “about:preferences” in the address line, and this brings us to the settings.</p>

<h4 id="generally" id="generally">Generally</h4>

<p>In the general settings, we will deactivate the following options:</p>
<ul><li>Recommend extensions while browsing</li>
<li>Recommend functions while browsing</li></ul>

<h4 id="home" id="home">Home</h4>

<p>Here, we will disable the following options:</p>
<ul><li>Important pages</li>
<li>Recommended by Pocket</li>
<li>overview</li>
<li>Brief information</li></ul>

<h4 id="search" id="search">search</h4>

<p>We will remove all existing search engines and use Searx as the only standard search engine.</p>

<p>But what is SearXNG? It is a free metasearch engine that protects users&#39; privacy. To complete this, Searx does not share users&#39; IP addresses or search history with the search engines from which it collects results. <a href="https://docs.searxng.org/" rel="nofollow">Here</a>; you can find more information about SearXNG.</p>

<p>To add Searx as a search engine, we search <a href="https://searx.space/" rel="nofollow">here</a>, an instance that we want to use and open it.</p>

<p>Then, we click with the right click in the address bar, and we select the Add Search Engine option from the menu.</p>

<p>Now, we can set SearXNG as the default search engine in the search settings.</p>

<p>Another great alternative are:</p>
<ul><li><a href="https://www.qwant.com/" rel="nofollow">Qwant</a> is a search engine with no user tracking and no filter bubble</li>
<li><a href="https://www.startpage.com/" rel="nofollow">Startpage</a> is a search engine that provides Google search results with complete privacy protection</li></ul>

<h4 id="privacy" id="privacy">Privacy</h4>

<p>Under the item improved protection against activity tracking, we will select the Custom option and set the following settings.</p>
<ul><li>Cookies: all third-party cookies (some websites may no longer work)</li>
<li>Activity tracking content: in all windows</li>
<li>Secret digital currency calculator (crypto miner)</li>
<li>Identifier (fingerprint)</li></ul>

<p>When websites send “Do Not Track” information that their activities should not be tracked, we always set this option.</p>

<p>Under Cookies and website data, we will activate the following:</p>
<ul><li>Delete cookies and website data when you quit Firefox</li></ul>

<p>In the next step, we will deactivate the option to save access data and passwords.</p>

<p>And finally, we will deactivate the following options under Data collection by Firefox and its use:</p>
<ul><li>Allow Firefox to send data on technical details and interactions to Mozilla</li>
<li>Allow personalized extension recommendations through Firefox</li>
<li>Allow Firefox to install and run studies</li></ul>

<h3 id="about-config" id="about-config">about:config</h3>

<p>Next, we go to the about:config page, then we can set further security-relevant options.</p>

<p>We type “about:config” in the Firefox address bar and press Enter. Then we press the “Accept risk and continue” button.</p>

<p>To change settings here, we copy the following settings (e.g., “webgl.disabled”), paste them into the search bar and set them to the specified value (e.g., “true”).</p>

<h4 id="disable-telemetry" id="disable-telemetry">Disable telemetry</h4>

<p>With the following changes, we will disable the Firefox telemetry:</p>
<ul><li>browser.newtabpage.activity-stream.feeds.telemetry = false</li>
<li>browser.ping-centre.telemetry = false</li>
<li>browser.tabs.crashReporting.sendReport = false</li>
<li>devtools.onboarding.telemetry.logged = false</li>
<li>toolkit.telemetry.enabled = false</li>
<li>Delete the URL for toolkit.telemetry.server, and leave it empty</li>
<li>toolkit.telemetry.unified = false</li></ul>

<h4 id="disable-pocket" id="disable-pocket">Disable Pocket</h4>

<p>If we don&#39;t use Pocket, or we don&#39;t want Firefox&#39;s Pocket integration, make the following changes:</p>
<ul><li>browser.newtabpage.activity-stream.section.highlights.includePocket = false</li>
<li>extensions.pocket.enabled = false</li></ul>

<h4 id="disable-javascript-in-pdf" id="disable-javascript-in-pdf">Disable JavaScript in PDF</h4>

<p>While there are legitimate uses for JavaScript in PDF (such as form validation), such uses are not very common. In addition, it could be used for malicious purposes, so it&#39;s generally a good idea to disable this feature.</p>

<p>pdfjs.enableScripting = false.</p>

<h4 id="security-ssl-require-safe-negotiation-true" id="security-ssl-require-safe-negotiation-true">security.ssl.require<em>safe</em>negotiation = true</h4>

<p>Making these changes will disable insecure SSL ciphers and force safe negotiation:</p>

<h4 id="privacy-trackingprotection-fingerprinting-enabled-true" id="privacy-trackingprotection-fingerprinting-enabled-true">privacy.trackingprotection.fingerprinting.enabled = true</h4>

<p>This option has been available since Firefox version 67, and it blocks fingerprinting.</p>

<h4 id="privacy-trackingprotection-cryptomining-enabled-true" id="privacy-trackingprotection-cryptomining-enabled-true">privacy.trackingprotection.cryptomining.enabled = true</h4>

<p>This option has been available since Firefox version 67 and this blocks CryptoMining.</p>

<h4 id="privacy-trackingprotection-enabled-true" id="privacy-trackingprotection-enabled-true">privacy.trackingprotection.enabled = true</h4>

<p>This is Mozilla&#39;s new built-in tracking protection. One of the benefits is to block tracking (i.e., Google Analytics) on privileged pages that have add-ons that normally do this disabled.</p>

<p>Privileged pages are those web pages that browser developers consider legitimate web pages, on which extensions tasked not to work / whose functionality has been completely stopped.</p>

<p>In Firefox, for example:</p>
<ul><li>accounts-static.cdn.mozilla.net</li>
<li>accounts.firefox.com</li>
<li>addons.cdn.mozilla.net</li>
<li>addons.mozilla.org</li>
<li>api.accounts.firefox.com</li>
<li>content.cdn.mozilla.net</li>
<li>content.cdn.mozilla.net</li>
<li>discovery.addons.mozilla.org</li>
<li>input.mozilla.org</li>
<li>install.mozilla.org</li>
<li>oauth.accounts.firefox.com</li>
<li>profile.accounts.firefox.com</li>
<li>support.mozilla.org</li>
<li>sync.services.mozilla.com</li>
<li>testpilot.firefox.com</li></ul>

<h4 id="browser-send-pings-false" id="browser-send-pings-false">browser.send_pings = false</h4>

<p>The attribute is useful for websites to keep track of visitor clicks.</p>

<h4 id="browser-urlbar-speculativeconnect-enabled-false" id="browser-urlbar-speculativeconnect-enabled-false">browser.urlbar.speculativeConnect.enabled = false</h4>

<p>By doing this, we disable the preloading of autocomplete URLs. Firefox preloads URLs that are autocomplete when a user types in the address bar. This is a problem when suggesting URLs that we don&#39;t want to connect too.</p>

<h4 id="dom-event-clipboardevents-enabled-false" id="dom-event-clipboardevents-enabled-false">dom.event.clipboardevents.enabled = false</h4>

<p>We disable that websites can receive notifications when we copy, paste or cut something from a website. This will tell you which part of the page has selected.</p>

<h4 id="media-eme-enabled-false" id="media-eme-enabled-false">media.eme.enabled = false</h4>

<p>Disables playback of DRM-controlled HTML5 content. When this option enabled, the Widevine Content Decryption Module provided by Google Inc. will be downloaded automatically.</p>

<h4 id="media-navigator-enabled-false" id="media-navigator-enabled-false">media.navigator.enabled = false</h4>

<p>Websites can track the microphone and camera status of our device.</p>

<h4 id="network-cookie-cookiebehavior-1" id="network-cookie-cookiebehavior-1">network.cookie.cookieBehavior = 1</h4>

<p>Disable cookies</p>
<ul><li>0 = Accept all cookies by default</li>
<li>1 = only accept from the original website (block third-party cookies)</li>
<li>2 = Block all cookies by default</li></ul>

<h4 id="network-http-referer-xoriginpolicy-2" id="network-http-referer-xoriginpolicy-2">network.http.referer.XOriginPolicy = 2</h4>

<p>We only send the referer header if the full host names match. (Note: if we notice a significant fraction, we can try 1 with a XOriginTrimmingPolicy optimization below.)</p>
<ul><li>0 = send referrer in all cases</li>
<li>1 = send referrer to the same eTLD sites</li>
<li>2 = only send referrer if full host names match</li></ul>

<h4 id="network-http-referer-xorigintrimmingpolicy-2" id="network-http-referer-xorigintrimmingpolicy-2">network.http.referer.XOriginTrimmingPolicy = 2</h4>

<p>When we send the referrer across origins, we only send the schema, host, and port in the referer header of cross origins requests.</p>
<ul><li>0 = send complete URL in the referrer</li>
<li>1 = send URL without query string in referrer</li>
<li>2 = Send only the scheme, host, and port in the referrer</li></ul>

<h4 id="webgl-disabled-true" id="webgl-disabled-true">webgl.disabled = true</h4>

<p>WebGL is a potential security risk.</p>

<h4 id="browser-sessionstore-privacy-level-2" id="browser-sessionstore-privacy-level-2">browser.sessionstore.privacy_level = 2</h4>

<p>This setting controls when to save additional information about a session: form, content, scrollbar positions, cookies, and POST data.</p>
<ul><li>0 = save additional session data for any site. (Standard from Firefox 4.)</li>
<li>1 = save additional session data only for unencrypted (not HTTPS) sites. (Default before Firefox 4.)</li>
<li>2 = never save additional session data.</li></ul>

<h4 id="beacon-enabled-false" id="beacon-enabled-false">beacon.enabled = false</h4>

<p>Disabled sending additional analysis to web servers.</p>

<h4 id="browser-safebrowsing-downloads-remote-enabled-false" id="browser-safebrowsing-downloads-remote-enabled-false">browser.safebrowsing.downloads.remote.enabled = false</h4>

<p>Prevents Firefox from sending information about downloaded executables to Google Safe Browsing to see if they should be blocked for security reasons.</p>

<h4 id="we-re-turning-off-the-firefox-prefetch-pages-which-we-expect-to-visit-next" id="we-re-turning-off-the-firefox-prefetch-pages-which-we-expect-to-visit-next">We&#39;re turning off the Firefox prefetch pages, which we expect to visit next:</h4>

<p>Even though prefetching may speed things up a bit, it may connect to servers without user intervention (which can be a privacy issue) and its performance benefits are minimal. Making these changes will disable prefetching:</p>
<ul><li>network.dns.disablePrefetch = true</li>
<li>network.dns.disablePrefetchFromHTTPS = true</li>
<li>network.predictor.enabled = false</li>
<li>network.predictor.enable-prefetch = false</li>
<li>network.prefetch-next = false</li></ul>

<h4 id="network-idn-show-punycode-true" id="network-idn-show-punycode-true">network.IDN<em>show</em>punycode = true</h4>

<p>Unless we render IDNs as punycode equivalent, we are open to phishing attacks, which are very difficult to detect.</p>

<h4 id="extensions-pocket-enabled-false" id="extensions-pocket-enabled-false">extensions.pocket.enabled = false</h4>

<p>This deactivates the Pocket Service.</p>

<h4 id="identity-fxaccounts-enabled-false" id="identity-fxaccounts-enabled-false">identity.fxaccounts.enabled = false</h4>

<p>We will disable the Firefox Sync Service. I will introduce you to better alternatives. We could also use a self-hosted sync server—the code is available on
<a href="https://github.com/mozilla-services/syncserver" rel="nofollow">GitHub</a>. But the service is currently still using outdated Python 2.7 code, and the service has ported to Rust meanwhile. And the other problem is that the self-hosted service does not currently work with mobile Firefox.</p>

<h4 id="identity-fxaccounts-toolbar-enabled-false" id="identity-fxaccounts-toolbar-enabled-false">identity.fxaccounts.toolbar.enabled = false</h4>

<p>We&#39;re removing the Firefox Accounts icon from the toolbar.</p>

<h4 id="disable-webrtc" id="disable-webrtc">disable WebRTC</h4>

<p>WebRTC can potentially expose your real IP address, changing the following disables it</p>

<p>We can change the following value to be sure that every WebRTC-related are really disabled.</p>
<ul><li>media.peerconnection.turn.disable = true</li>
<li>media.peerconnection.use<em>document</em>iceservers = false</li>
<li>media.peerconnection.video.enabled = false</li>
<li>media.peerconnection.identity.timeout = 1</li></ul>

<p>Hint: This will break any site that uses real-time audio/video communication, which includes almost all real-time chat and conferencing apps.</p>

<h2 id="add-ons" id="add-ons">Add-ons</h2>

<p>In this section, I would like to introduce you to a few useful add-ons for Firefox.</p>

<h3 id="ublock-origin-https-addons-mozilla-org-de-firefox-addon-ublock-origin" id="ublock-origin-https-addons-mozilla-org-de-firefox-addon-ublock-origin"><a href="https://addons.mozilla.org/de/firefox/addon/ublock-origin/" rel="nofollow">uBlock Origin</a></h3>

<p>An efficient blocker: low memory footprint and low CPU load, yet thousands more filters applied than other popular blockers.</p>

<h3 id="xbrowsersync-https-www-xbrowsersync-org" id="xbrowsersync-https-www-xbrowsersync-org"><a href="https://www.xbrowsersync.org/" rel="nofollow">xBrowserSync</a></h3>

<p>xBrowserSync synchronizes bookmarks between devices and browsers with end-to-end encryption. Data encrypted and decrypted on the device—nobody but us can read it. No registrationrequired. We just enter a randomly generated ID or QR code on all of our devices. There are <a href="https://www.xbrowsersync.org" rel="nofollow">different servers</a> available, which can also be <a href="https://github.com/xbrowsersync/api-docker" rel="nofollow">self-hosted</a>.</p>

<h3 id="canvasblocker-https-addons-mozilla-org-de-firefox-addon-canvasblocker" id="canvasblocker-https-addons-mozilla-org-de-firefox-addon-canvasblocker"><a href="https://addons.mozilla.org/de/firefox/addon/canvasblocker/" rel="nofollow">CanvasBlocker</a></h3>

<p>This add-on enables us to prevent websites from identifying us via Javascript APIs. We can choose whether the APIs completely blocked on certain or all pages (this will impair the functionality of some pages) or to fake wrong values for the identification-friendly readout functions.</p>

<h3 id="chameleon-https-addons-mozilla-org-de-firefox-addon-chameleon-ext" id="chameleon-https-addons-mozilla-org-de-firefox-addon-chameleon-ext"><a href="https://addons.mozilla.org/de/firefox/addon/chameleon-ext/" rel="nofollow">Chameleon</a></h3>

<p>With this add-on, we falsify our browser profile. It includes some privacy enhancement options.~~~~</p>

<h3 id="localcdn-https-addons-mozilla-org-de-firefox-addon-localcdn-fork-of-decentraleyes" id="localcdn-https-addons-mozilla-org-de-firefox-addon-localcdn-fork-of-decentraleyes"><a href="https://addons.mozilla.org/de/firefox/addon/localcdn-fork-of-decentraleyes/" rel="nofollow">LocalCDN</a></h3>

<p>This add-on emulates external frameworks (e.g., jQuery, Bootstrap, AngularJS) and makes them available as a local resource. It prevents unnecessary third-party requests like Google, StackPath, MaxCDN, and more. It contains prepared rules for uBlock Origin / uMatrix.</p>

<h3 id="redirect-amp-to-html-https-addons-mozilla-org-de-firefox-addon-amp2html" id="redirect-amp-to-html-https-addons-mozilla-org-de-firefox-addon-amp2html"><a href="https://addons.mozilla.org/de/firefox/addon/amp2html/" rel="nofollow">Redirect AMP to HTML</a></h3>

<p>Automatically redirects all AMP (Accelerated Mobile Page) pages to their regular HTML equivalent.</p>

<p>When we see an AMP page, we are likely seeing a page served directly by Bing or Google that can pull up information about what we&#39;re doing on that page. We keep the web decentralized, and we say, “No!” to search engines that want to take control of the web.</p>

<p>AMP pages designed for devices with a small screen and often do not translate well to larger screens. The extension can be especially useful
when we receive links from people who are on their mobile devices while we are on our desktop computer.</p>

<h3 id="adblocker-for-youtube-https-addons-mozilla-org-de-firefox-addon-adblock-for-youtube" id="adblocker-for-youtube-https-addons-mozilla-org-de-firefox-addon-adblock-for-youtube"><a href="https://addons.mozilla.org/de/firefox/addon/adblock-for-youtube" rel="nofollow">AdBlocker for YouTube</a></h3>

<p>This add-on removes all annoying ads from YouTube.</p>

<p>Important functions:</p>
<ul><li>Removes video and display ads from YouTube</li>
<li>Loads the YouTube website and videos faster</li>
<li>Supports both Firefox desktop and mobile (Android)</li></ul>

<h3 id="youtube-nonstop-https-addons-mozilla-org-de-firefox-addon-youtube-nonstop" id="youtube-nonstop-https-addons-mozilla-org-de-firefox-addon-youtube-nonstop"><a href="https://addons.mozilla.org/de/firefox/addon/youtube-nonstop" rel="nofollow">YouTube NonStop</a></h3>

<p>Tired of seeing the “Video paused. Continue watching?” Confirmation dialog? This extension will automatically click it, so you can listen to your favorite music without interruption.</p>

<p>The add-on works with YouTube and YouTube Music!</p>

<p><a href="https://remark.as/p/danschmid/install-firefox-under-freebsd-and-set-it-up-with-privacy" rel="nofollow">Discuss...</a></p>


]]></content:encoded>
      <guid>https://danschmid.writeas.com/install-firefox-under-freebsd-and-set-it-up-with-privacy</guid>
      <pubDate>Sat, 17 Sep 2022 18:09:06 +0000</pubDate>
    </item>
  </channel>
</rss>