Skip to content

Instantly share code, notes, and snippets.

@ethaniel
ethaniel / readme.md
Last active April 25, 2024 16:23
How to setup a Nordvpn client inside a docker container, running on a Raspberry Pi, and then route some computers on the local network through it

Intro

I live in Thailand. Sometimes my internet connection is slow, because my ISP has poor international connectivity with some destinations (Europe, for instance). Sometimes routes that the ISP chooses have a lot of packet losses, or just slow. I needed a way to route SOME of the devices on my LAN another way. I decided to use NordVPN because they have a lot of servers worldwide and my ISP provides a reliable route to SOME of them (I use docker run -it trishmapow/nordvpn-tools FR --load 30 --fping | awk '{ print $NF,$0 }' | sort -k1,1 -n | cut -f2- -d' ' | head -n 10 to find the best servers with the lowest ping for instance). However, I didn't want to deal with installing a VPN client on every device, so I decided to make one inside my Raspberry (but without having the Raspberry use the VPN connection itself, because I have other services running on it).

You will need

  1. Raspberry Pi wired by LAN cable
  2. Through raspi-config go to Advanced options - Network Interface Names - choose No to
@ethaniel
ethaniel / sms-to-telegram.md
Last active April 9, 2024 03:44
HOWTO: Receive SMS via 4G/LTE Huawei stick on Raspberry Pi 4 and forward them via Telegram

HOWTO: Receive SMS via 4G/LTE Huawei stick on Raspberry Pi 4 and forward them via Telegram

I live abroad and have only 1 sim card slot in my phone. It holds the SIM card of the country that I am in right now. But I also have another SIM card from my home country which receives my banking SMS codes. I can't afford to lose the "home" SIM card, so I decided to keep it in my house and forward the SMS messages to my main phone and computer via Telegram (just like Whatsapp, but so much better).

I also made a choice to use a 4G/LTE stick instead of 3G, because the 3G signal in my area is getting worse in worse due to operators upgrading their equipment.

Prerequisites

  1. Raspberry Pi 4
  2. Huawei E8372 (but can be any similar)

Step 1 - Get the Huawei card to work properly with Raspberry

@ethaniel
ethaniel / readme.md
Last active March 26, 2024 18:14
Hikvision NVR updates camera settings (SVC, Framerate) automatically.

If you don't want this, then enable ONVIF on every camera in the settings (add a new ONVIF user with the privilege "Media operator"), and then change the protocol to ONVIF on the NVR side.

@ethaniel
ethaniel / ceph_deep_scrub.php
Last active March 5, 2024 22:56
This script controls Ceph deep scrubs, making sure that each OSD is busy with a deep scrub.
<?php
/*
Script to always have 1 deep scrub running per OSD.
## About
1. Helps with the following error: PG_NOT_DEEP_SCRUBBED HEALTH_WARN (N pgs not deep-scrubbed in time)
2. Doesn't run scrubbing on PGs that were deep scrubbed less than 2 weeks ago, releasing
@ethaniel
ethaniel / hikvision.php
Created March 1, 2024 18:40
Simple PHP script to connect to Hikvision notification API
<?php
// Composer dependencies:
// composer require amphp/socket amphp/byte-stream
// IMPORTANT: Go to System > Security -> Authentication tab, set "WEB Authentication" to "digest/basic" first!!!
// Otherwise you will get authentication errors
require __DIR__ . '/vendor/autoload.php';
@ethaniel
ethaniel / ftp_server.php
Last active March 1, 2024 12:46
Simple FTP Server written in PHP to receive images from Hikvision cameras
<?php
require __DIR__ . '/vendor/autoload.php';
use Amp\Loop;
use Amp\Socket\Socket;
use function Amp\asyncCall;
$port1 = 1021; // Primary FTP port (you list it in Hikvision), it receives FTP commands
$port2 = 1022; // Secondary FTP port (for receiving binary data - images)
@ethaniel
ethaniel / gstreamer_rtsp_to_shm.md
Last active March 1, 2024 00:49
Split one RTSP stream into multiple gstreamer pipelines
  1. Get RTSP video, decode it, apply framerate and send to shared buffer. Don't forget to set shm-size to something high, because you're now dealing with decoded raw video:

gst-launch-1.0 -v rtspsrc location="rtsp://192.168.86.249/live/sala" protocols=tcp latency=1000 ! watchdog timeout=10000 ! rtph264depay ! h264parse ! avdec_h264 ! videorate ! video/x-raw,framerate=30/1 ! shmsink wait-for-connection=false socket-path=/tmp/foo shm-size=100000000

  1. Note the caps in the output:

/GstPipeline:pipeline0/GstShmSink:shmsink0.GstPad:sink: caps = video/x-raw, format=(string)I420, width=(int)2560, height=(int)1440, interlace-mode=(string)progressive, pixel-aspect-ratio=(fraction)1/1, chroma-site=(string)mpeg2, colorimetry=(string)1:0:0:0, framerate=(fraction)30/1

  1. Read decoded video from shared buffer (input the width,height,format,framerate caps from above):
@ethaniel
ethaniel / remove_icc.php
Created January 31, 2024 13:39
Solution for: icc_transform error. Message: libvips error: icc_transform: no output profile
<?php
// If you are using PHP Imagine, then you can catch the "icc_transform error. Message: libvips error: icc_transform: no output profile" error
// Then you need to remove the icc-profile-data and repeat the call
try {
$img = $img->thumbnail($box, Imagine\Image\ImageInterface::THUMBNAIL_OUTBOUND);
} catch (\Exception $e) {
if (strstr($e->getMessage(), "icc")) {
$img->getVips()->remove('icc-profile-data');
@ethaniel
ethaniel / delete.js
Last active January 11, 2024 08:12
Batch/bulk delete Cloudflare DNS records without API
// Copy-paste this into your browser's console.
// WARNING: This will delete ALL DNS RECORDS that are visible on the current page one by one.
// It might take 5-10 seconds to delete one DNS record.
// Based on https://community.cloudflare.com/t/useful-script-to-bulk-delete-all-incorrectly-imported-dns-records/131144
// Valid for 11 January 2024. Might need to be redone later.
(() => {
const deleteTopRecord = () => {
if (document.querySelector('[data-testid="dns-delete-modal-confirm-button"]')) {
@ethaniel
ethaniel / readme.md
Last active February 4, 2023 18:47
Grafana: Highlight 12 hour intervals in graphs for easier viewing
  1. Open Grafana dashboard settings.
  2. Go to "Annotations"
  3. Create an annotation with a data source "InfluxDB" and add the following query:
import "array"
import "timezone"
import "date"

option location = timezone.location(name: "Asia/Bangkok")