git reset [filename]
will undo a previous git add [filename]
call – one could say, it un-adds filename
git reset [filename]
will undo a previous git add [filename]
call – one could say, it un-adds filename
Use .ndim == 1
which contains the number of dimensions in the array.
if a.ndim == 1: print('a is a 1D array') else: print('a is not a 1D array')
You can also use assert
to check that:
assert a.ndim == 1
which will raise
an AssertionError
if a
is not a one-dimensional array.
The following example uses MikroTik scripting to iterate over all ethernet
interfaces and print the name of the interface:
foreach v in=[/interface/ethernet find] do={ :put [/interface/ethernet get $v value-name=name] }
Example output:
[admin@MySwitch] > foreach v in=[/interface/ethernet find] do={:put [/interface/ethernet get $v value-name=name]} ether1 sfp-CoreSwitch-Uplink sfp-sfpplus3 sfp-NAS sfp-Virtualization sfp-WAN sfp-sfpplus4 sfp-sfpplus7 sfp-sfpplus8
When using Google Search Console, you might want to submit your sitemap manually from time to time to accelerate indexing of new content on your website.
The following Tapermonkey script will automatically fill in sitemap.xml
and click the Send
button. Depending on your language setting, you will need to adjust the document.querySelector()
calls and modify the script header according to your domain (mydomain.com
in this example):
// ==UserScript== // @name SearchConsoleAutoFillSitemap // @namespace http://tampermonkey.net/ // @version 0.1 // @description ? // @author You // @match https://search.google.com/search-console/sitemaps?resource_id=https%3A%2F%2Fmydomain.com%2F&hl=de // @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net // @grant none // ==/UserScript== (function() { 'use strict'; // Simulate input let elem = document.querySelector("input[aria-label='Sitemap-URL eingeben']"); elem.value = "sitemap.xml"; elem.dispatchEvent(new Event('input', { bubbles: true, cancelable: true, })); // Click "Send" button setTimeout(() => { console.log("Clicking Send button"); document.querySelector("c-wiz[data-node-index='2;0'] div[tabindex='0']").click(); }, 500); })();
This snippet will change an input programmatically and then dispatch an input
event which will tell the javascript code running on the page that the input has changed.
let myinput = document.querySelector("input#myinput"); // Set value myinput.value = "newvalue"; // Simulate input event myinput.dispatchEvent(new Event('input', { bubbles: true, cancelable: true, }));
This Tapermonkey script will find <input id="myinput">
and set its value to newvalue
.
(function() { 'use strict'; document.querySelector("input#myinput").value = "newvalue"; })();
You’ll need to add a suitable header – it’s often best just to use the default template and modify only the URL.
First, create a directory for netbox
and all its data to reside in. In this example, we’ll use /opt/services/netbox.mydomain.com
. Place all files (unless mentioned otherwise) in said directory.
Obviously, generate new passwords and enter the correct domain name.
[email protected] SUPERUSER_PASSWORD=Soogohki0eidaQu4zaW9EjaBiuseeW POSTGRES_PASSWORD=chied2EatoZ1EFeish1OixaiVee7ae DOMAIN=netbox.mydomain.com
You shouldn’t need to modify anything here (except for the port)
version: "3.7" services: netbox-db: image: postgres:15-alpine restart: unless-stopped volumes: - ./pg_data:/var/lib/postgresql/data environment: - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - POSTGRES_DB=netbox - POSTGRES_USER=netbox netbox-redis: image: redis:7-alpine user: 1000:1000 command: redis-server restart: always volumes: - ./redis_data:/data netbox: image: lscr.io/linuxserver/netbox:latest container_name: netbox environment: - PUID=1000 - PGID=1000 - TZ=Europe/Berlin - SUPERUSER_EMAIL=${SUPERUSER_EMAIL} - SUPERUSER_PASSWORD=${SUPERUSER_PASSWORD} - ALLOWED_HOST=${DOMAIN} - DB_NAME=netbox - DB_USER=netbox - DB_PASSWORD=${POSTGRES_PASSWORD} - DB_HOST=netbox-db - DB_PORT=5432 - REDIS_HOST=netbox-redis - REDIS_PORT=6379 #- REDIS_PASSWORD=<REDIS_PASSWORD> - REDIS_DB_TASK=0 # Database ID for tasks - REDIS_DB_CACHE=1 # Database ID for cache #- BASE_PATH=<BASE_PATH> #optional #- REMOTE_AUTH_ENABLED=<REMOTE_AUTH_ENABLED> #optional #- REMOTE_AUTH_BACKEND=<REMOTE_AUTH_BACKEND> #optional #- REMOTE_AUTH_HEADER=<REMOTE_AUTH_HEADER> #optional #- REMOTE_AUTH_AUTO_CREATE_USER=<REMOTE_AUTH_AUTO_CREATE_USER> #optional #- REMOTE_AUTH_DEFAULT_GROUPS=<REMOTE_AUTH_DEFAULT_GROUPS> #optional #- REMOTE_AUTH_DEFAULT_PERMISSIONS=<REMOTE_AUTH_DEFAULT_PERMISSIONS> #optional volumes: - ./netbox_config:/config ports: - 13031:8000 depends_on: - netbox-db - netbox-redis restart: unless-stopped
Place this e.g. in /etc/nginx/sites-enabled/netbox-mydomain.conf
.
server { server_name netbox.mydomain.com; location / { proxy_pass http://localhost:13031/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; proxy_redirect default; } listen [::]:443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot } server { if ($host = netbox.mydomain.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name netbox.mydomain.com; listen [::]:80; # managed by Certbot return 404; # managed by Certbot }
After that, use our script to automatically create a systemd service & autostart Netbox on boot:
curl -fsSL https://techoverflow.net/scripts/create-docker-compose-service.sh | sudo bash /dev/stdin
Also, reload the nginx config:
sudo service nginx reload
When trying to operate netbox behind an nginx reverse proxy, you see the following log messages:
netbox | Invalid HTTP_HOST header: 'localhost:13031'. You may need to add 'localhost' to ALLOWED_HOSTS. netbox | Bad Request: /
Set the Host
header in the proxied requests using
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name;
in order to tell Netbox which host was originally requested (else, it will assume localhost
).
The following location
config works fine with Netbox:
location / { proxy_pass http://localhost:13031/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name; proxy_redirect default; }
server { server_name netbox.mydomain.com; location / { proxy_pass http://localhost:13031/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Host $server_name; proxy_redirect default; } listen [::]:443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot } server { if ($host = netbox.mydomain.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name netbox.mydomain.com; listen [::]:80; # managed by Certbot return 404; # managed by Certbot }
In the default configuration, you can use snmpwalk
using SNMPv1 to query information from the MikroTik RB260GS or RB260GSP.
snmpwalk -v1 -c public IPADDRESS
for example:
snmpwalk -v1 -c public 192.168.88.1
In order to get the Client ID
, Site ID
and authkey
for manual installation of a tactical RMM client, click on the Agents
menu and click Install Agent
:
This will open the Install Agent
window. Leave Windows selected even if you are installing for Linux! Select Manual
install at the bottom
After you click Show manual installation instructions
, you will see the following window, from which you can copy & paste the Client ID
, Site ID
and authkey
:
The following command will create a certificate with a subject alternative name (SAN) representing a self-signed wildcard certificate.
openssl req -x509 -sha512 -days 365000 -nodes -out cert.pem -newkey ed25519 -keyout privkey.pem -subj "/CN=mydomain.com" -addext "subjectAltName=DNS:*.mydomain.com"
Using this approach, no config file is required – all parameters can be passed using just the command line arguments.
You can just install mosquitto_sub
on OpenWRT routers such as on the Teltonika RUTX10/RUTX11 or TRB series using opkg
:
opkg update opkg install mosquitto-client
In case you see error messages like
* check_data_file_clashes: Package libmosquitto-nossl wants to install file /usr/lib/libmosquitto.so But that file is already provided by package * libmosquitto-ssl * check_data_file_clashes: Package libmosquitto-nossl wants to install file /usr/lib/libmosquitto.so.1 But that file is already provided by package * libmosquitto-ssl * opkg_install_cmd: Cannot install package mosquitto-client.
install mosquitto-client-ssl
instead:
opkg install mosquitto-client-ssl
Tested on firmware TRB1_R_00.07.02.6
.
You can just install tcpdump
on OpenWRT such as on the Teltonika RUTX10/RUTX11 or TRB series using opkg
:
opkg update opkg install tcpdump
Tested on firmware TRB1_R_00.07.02.6
.
In order to factory reset the GS710TUP switch but maintain NETGEAR registration status, press the RESET
button on the front panel (left side) for 5 seconds. You can press the button for any time between 5 and 9 seconds, but do not press the button for more than 10 seconds. Pressing the RESET
button for more than 10 seconds will perform a factory reset but also delete the registration status.
Source: GS710TUP user manual
In our previous post How to automatically re-resolve DNS in Wireguard on Linux we explored how to use the reresolve-dns.sh
script that is included with wireguard-tools on Ubuntu to re-resolve DNS entries in wireguard config files.
Add the following to the root crontab using crontab -e
:
* * * * * /usr/local/bin/reresolve-dns.sh /etc/wireguard/mywg.conf
You need to add this for every wireguard config (mywg.conf for this example).
The following command will capture ping request/replies (ICMP echo request / replies) on eth0 and (due to -v
will decode and display them):
tcpdump -i eth0 -v 'icmp'
13:51:16.007460 IP (tos 0x0, ttl 255, id 1522, offset 0, flags [none], proto ICMP (1), length 56) 10.158.211.2 > 10.158.211.1: ICMP echo request, id 32000, seq 2982, length 36 13:51:16.007484 IP (tos 0x0, ttl 64, id 37357, offset 0, flags [none], proto ICMP (1), length 56) 10.158.211.1 > 10.158.211.2: ICMP echo reply, id 32000, seq 2982, length 36
If you have a Wireguard config file such as /etc/wireguard/wghome.conf
, which you can start manually using wg-quick up wghome
, this is how you autostart it on boot. Thanks to Justin Ludwig on Serverfault for the template for that init script
Create /etc/init.d/wg-quick-wghome
:
#!/sbin/openrc-run description="wg-quick wghome" depend() { need net need localmount } start() { wg-quick up schlaftier } stop() { wg-quick down schlaftier }
Then make it executable:
chmod a+x /etc/init.d/wg-quick-wghome
and enable it to start on boot:
rc-update add wg-quick-wghome default
and start it right now if desired:
/etc/init.d/wg-quick-wghome start
Of course you can add multiple scripts like this. Just ensure to name them differently and perform all the steps required to enable startup on boot.
You can run this simple command as root to enable IPv4 forwarding in Alpine Linux:
sysctl -w net.ipv4.ip_forward=1
This setting will not persist after reboot.
In order to make the setting persist, append net.ipv4.ip_forward=1
to /etc/sysctl.conf
:
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
You want to import your SSH public key for passwordless login to your MikroTik router using either the terminal or WebFig/WinBox (as described in our previous post How to import SSH key to MikroTik RouterOS for passwordless login).
However, during import you see the following error message in the terminal:
unable to load key file (wrong format or bad passphrase)!
or in WebFig:
Couldn't perform action - unable to load key file (wrong format or bad passphrase)! (6)
Either you are using an elliptic curve key (which is not supported by RouterOS at the moment) or you are using a file which is not an SSH key.
The file you are uploading should look like this:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6EyAUma+shOkTZ0a6WcipSb552WmQb8hTKvDOMxQ234HXAeuJg3KeJ8WdkbOIdYuNq08xBrpjinaRGSZwDqhAiQMMz6O3yfkGpWZNO26lBQkngspJU1w6HLXR9tRtRaqbXwc1kV0KS6quj4sRaGLHKMciTjx0cVbEQrLxBXIJvRl7a6w/VukE+c9LhcRBZTrYB6Er7vGMM7VtgThzq+reFnql4kicG83NuPHjC/9Z78ehxpSekSrBYTYMuqiC1m8RW/l0mI8TtkUAU/qnTuwMXqVh0oOPGSWe4qvnbjCThRkDIEuK19CyCr5uyvZTV268SftEKaKOB7wcjevZlR11 uli@uli-desktop
The most important aspect is that it needs to start with ssh-rsa
, else RouterOS won’t import it – RouterOS supports ed25519
keys since RouterOS 7.7, which is in beta at the time of writing this post.
You can generate a new keypair and save it to id_mikrotik
and id_mikrotik.pub
using
ssh-keygen -t rsa -b 8192 -f id_mikrotik
Important: You can not use elliptic curve keys (tested with ed25519
) as of RouterOS 7.9 – RSA keys will work!
First, upload the public key to the filesystem of the router using Files
– in the following image, the SSH key is listed at the bottom:
/user/ssh-keys/import user=admin public-key-file=id_mikrotik.pub
Now go to System -> Users
, open the SSH keys tab:
There, click Import SSH Key
open the user you want to add the public key for (typically admin
if you didn’t create other users before):
then click Import SSH Key
and the key will be active immediately