Tuesday, January 31, 2023

Sharing Files Over http Using Nodejs In Docker

Sometimes we just need to share some files over network to some friends, and need a solution that is easy and fast to setup, provided we already have docker installed in our machine.


First, prepare a directory. Then, put all the files that we want to share inside the directory
$ mkdir files

Then, run a container based on nodejs:slim image, and mount the above directory to our container, which is named "fileshare" in this example
$ docker run -dit -p 8080:80 --name fileshare -v $PWD:/files -w /files node:slim

Install http-server inside the container
$ docker exec -it fileshare npm install -g http-server 

Run http-server inside the container
$ docker exec -it fileshare http-server -p 80 .

You should now be able to view your files using a web browser. Just browse to your ip with port 8080 like below
















Once you are done, just press control-C on the terminal where the http-server is running, and the http-server will be terminated

Saturday, January 21, 2023

Scheduling Tasks With systemd.timer

Systemd.timer is a way to scheduling jobs and tasks in systemd based linux system. The systemd timer units are identified by ".timer" (dot timer) file name extension, compared to ".service" for service units. 

Each timer file requires a service file for it to work. In other word, systemd timers only can schedule systemd services.  

Some of systemd.timer features:
  1. timer is managed by systemd similar to other units, using systemctl command
  2. timers can be triggered by calendar event, or triggered by specific time elapsed from a certain starting point
  3. time units are logged to journal, for easier troubleshooting and monitoring
  4. if the system is off during the expected execution time, the timer will be executed when the system is running again
The usage of timer is best explained using an example. Let's say we want to create a timer to run a script called hello.sh.

First, we need to create the script, and get the location of the script. Let's say we created the script inside /usr/local/bin/hello.sh

Next, we need to create a systemd service unit for the above script. Just insert below settings into /etc/systemd/system/hello.service
[Unit]
Description="Hello app"

[Service]
ExecStart=/usr/local/bin/hello.sh

Then, create a systemd timer unit for hello.service. Just add below setting into /etc/systemd/system/hello.timer
[Unit]
Description="Run hello.service 5min after boot, every 24 hours relative to activation time, and everyday at 10:00 am"

[Timer]
OnBootSec=5min
OnUnitActiveSec=24h
OnCalendar=Mon..Fri *-*-* 10:00:*
Unit=helloworld.service

[Install]
WantedBy=multi-user.target

The above example will run the script after 5 minutes of system boot, 24 hours after the timer activation time, and everyday at 10:00am. The format for OnCalendar is as below
Day of Week = Sun to Sat
Date = in yyyy-mm-dd format
Time = in hour:minute:seconds format

For example, if we want to execute the script at 3:00 pm every Monday and Friday
OnCalendar=Mon,Fri *-*-* 15:00:00
Or execute the script at 4:00 pm 20 February 2023
OnCalendar=2023-02-20 16:00:00

For more example on setting the timer, we can type this command to see the manual page of systemd.time
# man 7 systemd.time

Before we use the new systemd unit files for hello.sh, we can verify that they are error free
# systemd-analyze verify /etc/systemd/system/hello.*

If no error detected, then we can start the timer
# systemctl start hello.timer

We can also enable the timer on boot
# systemctl enable hello.timer

To check the status of timer
# systemctl status hello.timer

To list all active timers
# systemctl list-timers 

To list all timers, regardless whether they are active or note
# systemctl list-timers --all

To stop the timer
# systemctl stop hello.timer

Wednesday, January 11, 2023

Change DNS server using resolvectl

For systemd based system, the configuration of dns resolution is controlled by a service called systemd-resolved.service.

In order to change the dns server that the machine refers to for any DNS request, we can use a command called resolvectl.

To set the current dns server in interface wlp4s0 to 1.1.1.1, use this command
sudo resolvectl dns wlp4s0 1.1.1.1

To set the dns server in interface wlp4s0 to 1.1.1.1 and 8.8.8.8, use this command
sudo resolvectl dns wlp4s0 1.1.1.1 8.8.8.8

We can specify as many dns servers as we like. Just separate them with spaces.

To check our currently set dns server for interface wlps4s0, use this command
resolvectl dns wlp4s0

We can see dns settings for all interfaces in the system by running
resolvectl status

We can also query (get the ip address from dns) record using resolvectl, just like below
resolvectl query www.linuxwave.info

To query different type of dns record, we can add the -t flag. This is an example if we want to query an MX record for gmail.com
resolvectl query -t MX gmail.com

We can also do reverse query, by specifying ip address instead of domain name

resolvectl query 142.250.191.51 

Thursday, January 5, 2023

SSH Tunnel That Listens To Non Loopback (Non Localhost) IP

In order for ssh tunnel to listen to non localhost interface, we have to enable "GatewayPorts" in /etc/ssh/sshd_config


1. Open /etc/ssh/sshd_config using your preferred text editor. I use vi
$ sudo vi /etc/ssh/sshd_config

2. Turn on "GatewayPorts" by adding below into /etc/ssh/sshd_config
GatewayPorts yes

3. Save and exit the text editor

4. Restart ssh
$ sudo systemctl restart ssh

5. Now we can create a local/remote tunnel, and the tunnel can be made to listen to non loopback (non localhost). For example, we can forward a port from another machine, and make it to listen to all ipv4 address in our local machine
$ ssh -R 0.0.0.0:1111:localhost:22

6. We can verify it by using ss command
$ sudo ss -tulpn | grep 1111
...
tcp   LISTEN 0      128                             0.0.0.0:1111        0.0.0.0:*                   users:(("sshd",pid=xxxxx,fd=10))