Blog

Blog

Install brew in MacOS 10.13.6

Install brew in MacOS 10.13.6

Steps

Download following packages, install first two packages.

Xcode_10.1.xip
Command_Line_Tools_macOS_10.13_for_Xcode_10.1.dmg
Kernel_Debug_Kit_10.13.6_build_17G10017.dmg
Swift_5_Runtime_Support_for_Command_Line_Tools.dmg
Swift_Playgrounds_Author_Template_for_Xcode_10.xip
Font_Tools_for_Xcode_11.dmg
Additional_Tools_for_Xcode_10.1.dmg

Run following command to install

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

References

All Downloads
Install Homebrew ยท Mac M1

NextCloud menu display incorrectly

NextCloud menu display incorrectly

A strange error happens in some browsers, NextCloud menu become a big page vertically, and one password textbox there requesting password, but the password is not working.

Not specific OS or browser

In my iMac, Safari is not working. In my one Windows machine, Firefox is not working. By the way, the Firefox has sync enabled and it is working in another PC. Google Chrome and Microsoft Edge have no issue.

Debugging

There is programming error, the contents were downloaded from following website directly, not the NextCloud server. Browser blocked them.

https://raw.githubusercontent.com

Solution

Disable "Theming App" in NextCloud Apps screen.

References

NextCloud page not displaying correctly

The `sed` command uncommon behaviors

The sed command uncommon behaviors

The sed command is used in Unix, some strange behaviors can let time waste.

Escape char in regex

Normally, the \ is escape character, but it wasn't in some cases.

For example, . is to match any character, it needs to have \ as escape character if need it to be a dot character.

$ echo "test (111) help . 1" | sed -e "s/.//"
est (111) help . 1
$ echo "test (111) help . 1" | sed -e "s/\.//"
test (111) help  1

But this is not for (), without \, they are (), with \, they are indicating subpattern.

$ echo "test (111) help . 1" | sed -e 's/(111)//'
test  help . 1
$ echo "test (111) help . 1" | sed -e 's/\(111\)//'
test () help . 1
$ 

Same for {}

echo "test (111) help . 1" | sed -e 's/hel{1}p//'
test (111) help . 1
$ echo "test (111) help . 1" | sed -e 's/hel\{1\}p//'
test (111)  . 1

and ?

$ echo "test (111) help . 1" | sed -e 's/he?lp//'
test (111) help . 1
$ echo "test (111) help . 1" | sed -e 's/h?lp//'
test (111) help . 1
$ echo "test (111) help . 1" | sed -e 's/he\?lp//'
test (111)  . 1

* and +

The sed understands the meaning of *, but not for +.

$ echo "test (111) help . 1" | sed -e 's/hel*p//'
test (111)  . 1
$ echo "test (111) help . 1" | sed -e 's/hel+p//'
test (111) help . 1

\* and \+

The sed understands the meaning of \+, but not for \*.

$ echo "test (111) help . 1" | sed -e 's/hel\*p//'
test (111) help . 1
$ echo "test (111) help . 1" | sed -e 's/hel\+p//'
test (111)  . 1

Install App in NextCloud Manually

Install App in NextCloud Manually

Got issue to see AppStore in NextCloud, could not fix it.

Tried, but failed

Set appstore in config.php

Updated config.php with following options, but failed.

'appstoreenabled' => true,
'appstoreurl' => 'https://apps.nextcloud.com/api/v1',

But successfully using curl tested access to https://apps.nextcloud.com/api/v1.

Using occ

php occ app:list

Can not see Apps in AppStore

Manual installation

  • Download App from app.nextcloud.com, extract to nextcloud/apps folder.

  • Change owner to www-data:www-data

  • Go to GUI Apps => Disabled apps, refresh page

  • Then the app should be listed.

  • Click on install to install it.

References

Apps management
Using the occ command

Disable ICMPv6 Redirect Messages in Solaris

Disable ICMPv6 Redirect Messages in Solaris

As CIS requirements, ICMPv6 Redirect Messages should be disabled in Solaris.

Steps

Download two following files

cis_netconfig.sh
cis_netconfig.xml

Following commands are copied from CIS document, which is not clean. Just for reference.

cat > cis_netconfig.sh << END
#!/sbin/sh
ndd -set /dev/ip ip_forward_src_routed 0
ndd -set /dev/ip ip6_forward_src_routed 0
ndd -set /dev/tcp tcp_rev_src_routes 0
ndd -set /dev/ip ip_forward_directed_broadcasts 0
ndd -set /dev/tcp tcp_conn_req_max_q0 4096
ndd -set /dev/tcp tcp_conn_req_max_q 1024
ndd -set /dev/ip ip_respond_to_timestamp 0
ndd -set /dev/ip ip_respond_to_timestamp_broadcast 0
ndd -set /dev/ip ip_respond_to_address_mask_broadcast 0
ndd -set /dev/ip ip_respond_to_echo_multicast 0
ndd -set /dev/ip ip6_respond_to_echo_multicast 0
ndd -set /dev/ip ip_respond_to_echo_broadcast 0
ndd -set /dev/arp arp_cleanup_interval 60000
ndd -set /dev/ip ip_ire_arp_interval 60000
ndd -set /dev/ip ip_ignore_redirect 1
ndd -set /dev/ip ip6_ignore_redirect 1
ndd -set /dev/tcp tcp_extra_priv_ports_add 6112
ndd -set /dev/ip ip_strict_dst_multihoming 1
ndd -set /dev/ip ip6_strict_dst_multihoming 1
ndd -set /dev/ip ip_send_redirects 0
ndd -set /dev/ip ip6_send_redirects 0
END
chmod +x cis_netconfig.sh
cat > cis_netconfig.xml << END
<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<service_bundle type='manifest' name='CIS:cis_netconfig'>
  <service name='site/cis_netconfig' type='service' version='1'>
    <create_default_instance enabled='true' />
    <single_instance />

    <dependency name='usr' type='service' grouping='require_all' restart_on='none'>
      <service_fmri value='svc:/system/filesystem/minimal' />
    </dependency>

    <!-- Run ndd commands after network/physical is plumbed. -->
    <dependency name='network-physical' grouping='require_all' restart_on='none' type='service'>
      <service_fmri value='svc:/network/physical' />
    </dependency>

    <!-- but run the commands before network/initial -->
    <dependent name='ndd_network- initial' grouping='optional_all' restart_on='none'>
      <service_fmri value='svc:/network/initial' />
    </dependent>

    <exec_method type='method' name='start' exec='/lib/svc/method/cis_netconfig.sh' timeout_seconds='60' />
    <exec_method type='method' name='stop' exec=':true' timeout_seconds='60' />
    <property_group name='startd' type='framework'>
       <propval name='duration' type='astring' value='transient' />
    </property_group>

    <stability value='Unstable' />
    <template>
      <common_name>
        <loctext xml:lang='C'> CIS IP Network Parameter Set </loctext>
      </common_name>
    </template>
  </service>
</service_bundle>
END
cp cis_netconfig.sh /lib/svc/method
chmod 750 /lib/svc/method/cis_netconfig.sh
svccfg import cis_netconfig.xml

Create a service

# cp cis_netconfig.sh /lib/svc/method
# chmod 750 /lib/svc/method/cis_netconfig.sh
# svccfg import cis_netconfig.xml

References

CIS Oracle Solaris 10 Benchmark v5.2.0 - 09-02-2015 - Local Cache

Split NGINX configuration file

Split NGINX configuration file

To split NGINX configuration file into multiple conf.d/*.conf files.

This is defined in /etc/nginx/nginx.conf file as below

http {
    ...
    include /etc/nginx/conf.d/*.conf;
}

Pros

Avoid large configuration file and manage easiler.

NGINX will read all files in conf.d directory, which has extension name as .conf and use them all as final configuration.

Cons

Only definitions in http { ... } directive can be defined in conf.d/*.conf.

Which file to be loaded first is unclear.

One server definition should not be defined in mulitipe files.

Fix NextCloudPi Security & setup warnings

Fix NextCloudPi Security & setup warnings

Following warnings appear by default:

  • No default_phone_region configured
  • Imagick missing in PHP

Missing default_phone_region

Add following line in nextcloud/config/config.php:

...
  'default_phone_region' => 'SG',
}

Restart NextCloudPi.

Imagick missing in PHP

Install php-imagick package:

# docker exec -it nextcloudpi bash
# apt install php-imagick

Restart NextCloudPi.

Then new issue

Got following warning

Module php-imagick in this instance has no SVG support. For better compatibility it is recommended to install it.

Then run following commands

# docker exec -it nextcloudpi bash
# apt-get install libmagickcore-6.q16-6-extra

Restart NextCloudPi

References

Configuration Parameters
Imagick missing - version php 7.3
How to enable SVG for php-imagick

Enable 2FA for TrueNAS Core

Enable 2FA for TrueNAS Core

The 2FA in TrueNAS Core uses pam_oath.so module, supports Two-factor time based (TOTP) SSH authentication.

Setup

Enable 2FA

  • Go to Credentials => 2FA

  • Click on Enable Two-Factor Authentication

  • Click on Show QR, use Authy to record it. This is token for root account.

  • Save

Test GUI

Use another browser login with user name, password, and pin code (Authy generated).

Make sure it is working.

Enable SSH

  • Go to Credentials => 2FA

  • Select Enable Two-Factor Auth for SSH

  • Save

Enable root login

  • Go to System Settings => Services

  • Select Configure button, which is a pencil icon

  • Check Log in as Root with Password

  • Save

Test root login with 2FA

Use terminal

$ ssh host.example.com
Password: 
One-time password (OATH) for 'root':
Linux truenas.bx.net 5.10.70+truenas #1 SMP Wed Nov 3 18:30:34 UTC 2021 x86_64

Test root login successful.

Disable root login

  • Go to System Settings => Services

  • Select Configure button, which is a pencil icon

  • Uncheck Log in as Root with Password

  • Save

Setup for normal user

After enable 2FA, normal user can not login, got error in /var/log/auth.log as below:

error: PAM: User not known to the underlying authentication module for ...

Use these steps to enable 2FA for user.

Note: If you lost SSH connection, the root shell can be accessed from GUI, System Settings => Shell

Generate a random code

# head -10 /dev/urandom | md5sum | cut -b 1-30
15ad027b56c81672214f4659ffb432

Get oath configuration file name

The usersfile name can be found using following command:

# grep oath /etc/pam.d/sshd
auth    required    pam_oath.so    usersfile=/etc/users.oath    window=0

Update /etc/users.oath

Setup the oath seed in /etc/users.oath:

HOTP/T30/6  user    -   15ad027b56c81672214f4659ffb432

Install oathtool

Use another linux server, such as ubuntu server:

ubuntu# apt install oathtool

I chose another server, because TrueNAS server is not fully customized debian server, better don't change it structure and packages.

Test pin code for SSH

Open another terminal, and run following command, and run second command in the linux server when prompting OATH code.

$ ssh host.example.com
Password: 
One-time password (OATH) for 'user':

Now, quickly run following command,

ubuntu# oathtool --totp -v 15ad027b56c81672214f4659ffb432
960776

Input OATH code in SSH login terminal. The code should be accepted.

Get Base32 secret

In the previous ubuntu server, install qrencode package

ubuntu# apt install qrencode

Run following command to collect Base32 secret:

ubuntu# oathtool --totp -v 15ad027b56c81672214f4659ffb432
Hex secret: 15ad027b56c81672214f4659ffb432
Base32 secret: CWWQE62WZALHEIKPIZM77NBS
...
329770

Generate QR code

qrencode -t ansiutf8 "otpauth://totp/user@host.example.com?secret=CWWQE62WZALHEIKPIZM77NBS"

Save into Authy

Use Authy scan QR code, then type in TrueNAS in textbox to search icon, then save it.

Persistent change

As TrueNAS is a fully customized OS, it has startup process to regenerate /etc/users.oath file, results only root id stays.

In order to overcome this issue, create a startup command in System Settings => Advanced => Init/Shutdown Scripts, add following command:

Name: Append oath codes
When: POSTINIT
Command:

echo "HOTP/T30/6\t<user_name>\t-\t<user_code>" >> /etc/users.oath

Note: There are many ways to archive this, such as backup users.oath files you created, and restore it. I just chose the most easy and maintenance free way.

TrueNAS GUI

I could not find any place to setup in TrueNAS GUI for user, and the user id I created in TrueNAS can not login to GUI at all. In fact, TrueNAS doesn't support normal user login to GUI.

Possible enhancements

There are the limitations of pam_oath.o implemenation

Only one usersfile

Only one usersfile can be specified in pam_oath.o, there are some suggestions, such as:

  • Enhance source code to allow pam_oath.o accepts %h as usersfile parameter's value to point to user's home directory.

Missing entry allowed

If the user is not in usersfile, then they can not login, this makes administrator very busy.

I like one example implementation as below:

WARNING: I didn't test the following codes which downloaed from Two-Factor Authentication with OTP (Admin Guide), just for reference.

  • Create a group called otpusers, the users are not in this group do not require 2FA. This implemented in PAM
auth [success=2 default=ignore] pam_succeed_if.so uid = 0                        # skip 2 lines for root
auth [success=1 default=ignore] pam_succeed_if.so user notingroup otpusers       # ignore users not yet in otpusers
auth requisite pam_oath.so usersfile=/var/security/auth/users.oath window=20     # accept one of 20 consecutive keys 
 (in case clocks of user and server are out of sync)
 ```

* Create profile script to check whether the user is in `otpusers` group, if not, create oath code and allow user save it.

*WARNING: The below script that I copied from Internet got syntax error, and I didn't test it as well.*

`/etc/profile.d/create_secret.sh`:

/bin/bash

RRZK, 2015-12-10 (CO)

OATH_FILE="/var/security/auth/users.oath"
OTPGROUP="otpusers"

ME=$(/usr/bin/whoami)

ME=${PAM_USER}

HOST=${HOSTNAME}

RET=0
/usr/bin/id -Gn ${ME}|/bin/grep ${OTPGROUP} >/dev/null 2>&1
RET=$?

if [ ! ${ME} = "root" ] && [ ${RET} -ne 0 ]; then

Disable CTRL-C

trap '' 2

/bin/echo -e "

Hello ${ME}

I will generate a TOTP (time based) OATH Secret for you...
"

generate secret

/bin/echo "... generating secret"
SECRET=$(/usr/bin/head -10 /dev/urandom | /usr/bin/sha512sum | /bin/cut -b 19-50)

generate base32 secret

/bin/echo "... generating base32 secret"
BASE32=$(/usr/bin/oathtool --totp -v ${SECRET}|/bin/grep 'Base32'|/bin/awk '{print $NF}')

generate qrcode

/bin/echo "... generating qrcode"
/usr/bin/qrencode -l H -v 1 --background=FFFFFF -o ${ME}_oath.png "otpauth://totp/${ME}@${HOST}?secret=${BASE32}"

insert secret in oath database

/bin/echo "... adding secret to oath database"
/bin/echo "... adding user to otpuser group"

TMPFILE=$(/bin/mktemp ) || exit 1
/bin/echo -e "HOTP/T30/6\t${ME}\t-\t${SECRET}" > $TMPFILE
/usr/bin/sudo -u root /usr/local/sbin/add_secret.sh ${TMPFILE} ${OTPGROUP} ${ME}
/bin/rm -f TMPFILE

/bin/echo "... finished"
echo "Secret: ${SECRET}
BASE32 Secret:${BASE32}" > ${ME}_oath.dat

/bin/echo "
Your Secret is: ${SECRET}
Your BASE32 Secret is ${BASE32}
Your QR-Code is: ${ME}_oath.png

Enter your secret in your OTP Token (enter BASE32 without the trailing '=')
or
Display this file and scan it with your OTP Token APP. (X11Forward only)
"
/bin/echo "To display your QR-Code, press "
read INPUT
if [ "$INPUT" = "d" ]; then
/usr/bin/display ${ME}_oath.png
fi

logout
fi


* Then add oath code into *usersfile*.

*WARNING: The below script that I copied from Internet got syntax error, and I didn't test it as well.*

`/usr/local/sbin/add_secret.sh`:

/bin/bash

RRZK, 2015-12-10 (CO)

OATH_FILE=/var/security/auth/users.oath

TMPFILE=$1
OTPGROUP=$2
USER=$3

/bin/cat ${TMPFILE} >> ${OATH_FILE}
/usr/sbin/usermod -a -G ${OTPGROUP} ${USER}
exit 0



## References

[pam_oath](https://wiki.archlinux.org/title/Pam_oath)
[Two-factor time based (TOTP) SSH authentication with pam_oath and Google Authenticator](https://spod.cx/blog/two-factor-ssh-auth-with-pam_oath-google-authenticator.shtml)
[How to Create QR Codes From the Linux Command Line](https://www.cloudsavvyit.com/8382/how-to-create-qr-codes-from-the-linux-command-line/)
[How to generate a QR Code for Google Authenticator that correctly shows Issuer displayed above the OTP?](https://stackoverflow.com/questions/34520928/how-to-generate-a-qr-code-for-google-authenticator-that-correctly-shows-issuer-d)
[Enable user to login to webui](https://www.truenas.com/community/threads/unable-to-login-to-gui-with-non-admin-root-user.19921/)
[Two-Factor Authentication with OTP (Admin Guide)](https://hpc-wiki.info/hpc/Admin_Guide_Two-Factor_Authentication_with_OTP)
[sshd: How to enable PAM authentication for specific users under](https://serverfault.com/questions/222637/sshd-how-to-enable-pam-authentication-for-specific-users-under)

Split Home Network

Split Home Network

Note: Tested using KVM network only

Let's say, you want to have a network which is different than the one ISP setup for you.

Why

  • You may want to have a guest network, which outside your home network for guests.
  • You may want to have a network with full functional network devices, firewall, DNS server, DHCP server, etc.
  • You may want to monitor the network inbound and outbound traffic.
  • You may want to setup PXE, iPXE, BOOTP environment, configure DHCP options such as TFTP server, etc.
  • You may want the VMs running on KVM routable network provide services to all machines, including Internet.
  • You may want to have more IPs, want to have IP segments.
  • You may want to have a more secure environment. In fact, if your router was setup by ISP, then they got full control of it, not you.

So, can you setup your own router to replace ISP route? Yes, you can, but you need to know whether you are allowed to do so by ISP. For my case, they asked me sign new agreement to say, service level drop and no technique support provided.

Before split

  • You have a network which connect to ISP via the ISP route, which have DHCP and DNS service.

Requirement

  • The ISP route can add route.
  • One device or router with two network interfaces, and they are or can be on separate LAN.

Simple solution

If you have another router, let's say RouterA

  • Connect WAN port of RouterA to ISP route LAN port
  • Configure ISP LAN IP on RouterA's WAN port, such as 192.168.1.100,
  • Make sure RouterA is in router mode, with it's own LAN, such as 192.168.100.0/24
  • Add a route in ISP Route, network 192.168.100.0/24 gateway 192.168.1.10.

Done.

Difficult solution

Replace RouterA with your own home build router in the simple solution.