A few thingz
Update: many thanks to @Korben for his article:
nFreezer – De la sauvegarde chiffrée de bout en bout https://t.co/I4yea8IogI— Korben (@Korben) December 12, 2020
So you make backups of your sensitive data on a remote server. How to be sure that it is really safe on the destination server?
By safe, I mean "safe even if a malicious user gains access" on the destination server; here we're looking for a solution such that, even if a hacker attacks your server (and installs compromised software on it), they cannot read your data.
You might think that using SFTP/SSH (and/or
rsync, or sync programs) and using an encrypted filesystem on the server is enough. In fact, no: there will be a short time during which the data will be processed unencrypted on the remote server (at the output of the SSH layer, and before arriving at the filesystem encryption layer).
How to solve this problem? By using an encrypted-at-rest backup program: the data is encrypted locally, and is never decrypted on the remote server.
I created nFreezer for this purpose.
encrypted-at-rest: the data is encrypted locally (using AES), then transits encrypted, and stays encrypted on the destination server. The destination server never gets the encryption key, the data is never decrypted on the destination server.
incremental and resumable: if the data is already there on the remote server, it won't be resent during the next sync. If the sync is interrupted in the middle, it will continue where it stopped (last non-fully-uploaded file). Deleted or modified files in the meantime will of course be detected.
graceful file moves/renames/data duplication handling: if you move
/anotherpath/subdir/10GB_file_renamed, no data will be re-transferred over the network.
This is supported by some other sync programs, but very rarely in encrypted-at-rest mode.
stateless: no local database of the files present on destination is kept. Drawback: this means that if the destination already contains 100,000 files, the local computer needs to download the remote filelist (~15MB) before starting a new sync; but this is acceptable for me.
does not need to be installed on remote: no binary needs to be installed on remote, no SSH "execute commands" on the remote, only SFTP is used
- single .py file project: you can read and audit the full source code by looking at
nfreezer.py, which is currently < 300 lines of code.
More about this on nFreezer.
By the way I just published another (local) backup tool on PyPi:
backupdisk, that you can install with
pip install diskbackup. It allows you to quickly backup your disk to an external USB HDD in one-line:
diskbackup.backup(src=r'D:\Documents', dest=r'I:\Documents', exclude=['.mp4'])
After years of music production, photography, electronics, programming, <name your favorite creative field here>, or whatever, we probably all end up with the same situation: we accumulate a lot of gear.
Most of these items are (thankfully) working, some of them are broken (but we keep them just in case), and some others, well ... we don't really know, probably because we never properly identified them.
I'm speaking about USB cables, phone chargers/PSU (good and not-so-good ones), external hard drives that all look the same, microphones, XLR microphones cables, audio interfaces, etc.
Usually it's ok to use one item or another, but for special occasions (an important recording session / photography shooting / whatever), you don't want your work to be spoiled because, among 5 units, you picked the wrong laptop power supply, the only one that produces an annoying 50Hz buzz when recording audio.
Here is an easy rule to circumvent this problem:
All you need is to label your items with a 5-character ID
with a pen, some tape
and to make an inventory with your (tested) items:
But why random 5-alphanumeric characters? Because every time you'll want to label a new object, you won't have to worry about "Was this ID already taken or not in my inventory?"
With a very high, large enough probability, it will not be already taken.
To be more precise, if you label 1000 objects in your life with these 5-random-alphanumeric-char identifiers, you'll have a probability of 0.8 % that two objects have the same label. I think it's ok. This is a classical application of the math birthday problem.
I personnally don't care if once in my life two items have the same number in my inventory, but if I'd care, I would just use a 6-alphanumeric-character ID (in this case the probability of at least one collision is 0.02%).
Ok, this is just UUID applied to real life.
I can hear you saying:
"Well that's nonsense, I can just number the items #0001, #0002, and so on. Why a random alphanumeric ID?"
Reason #1: Let's say you have 5 cables around you. You label them #0001, #0002, ..., #0005. Two month laters you have a new cable with no label, and don't have the inventory handy. Where did I stop in the numbering the last time? I think I stopped at #0004, so let's label this one #0005. (1 hour later). Oops no no no, #0005 was already taken. But maybe #0006 as well? Well no problem, let's label it with #9999. (2 months later). How to label this new cable? Did I already have a #9998 or not?
As we can see using an increasing sequence requires us to remember where we stopped the previous time, and it's not convenient.
Reason #2: If you have multiple item types (cables, PSU, hard drives), you will have many objects numbered #0001, so it's not easy to find them in an inventory. Here you can have a single inventory file with all your stuff. Once again, it's unlikely that two items in your life will have the same label.
Interested by this kind of useless things?
For some projects you need a real code versioning system (like
git or similar tools).
But for some others, typically micro-size projects, you sometimes don't want to use a complex tool. You might want to move to git later when the project gets bigger, or when you want to publish it online, but using git for any small project you begin creates a lot of friction for some users like me. Examples:
User A: "I rarely use git. If I use it for this project, will I remember which commands to use in 5 years when I'll want to reopen this project? Or will I get stuck with
git wtf and unable to quickly see the different versions?".
User B: "I want to be able to see the different versions of my code even if no software like git is installed (ex: using my parents' computer)."
User C: "My project is just a single file. I don't want to use a complex versioning system for this. How can I archive the versions?"
For this reason, I just made this:
It is a (quick and dirty) versioning system, done in less than 50 lines of Python code.
Here is some 80s-cheeeeesy French pop I made with Gaëlle W. :
Install it here: FastReply Chrome extension
it works even if Gmail's SmartReply feature is enabled, both can work together
it works in Gmail and other webmails/websites
- another small but useful extension: ShowSubjectGmail
Interested for future evolutions and other (smarter) autoreply email tools?
(several other hour-saving tools in progress)
Painted together with my girlfriend some years ago ; this place is really inspiring. If you sometimes go from Paris to Orleans by train, you'll probably find where it is!
(Other pictures to be added here)
Why another lightweight notepad with encryption?
Well, I needed an encrypted notepad for personal notes that has these features:
- Ask a password on startup
- Don't re-ask for the password when saving since we already asked that when opening (except if it's a new file)
- Dark mode colors
- The unencrypted plaintext is never written to disk
- I wanted to be able to read the full source-code before using it, without spending 1 full day on it (so I finally wrote it in a few hours)
Here it is:
Day 1: the idea
Sometimes I play and record synthesizer for a song I'm producing, but somes notes here and there are out of rhythm... I wish they had been perfectly in the rhythm out-of-the-box! Indeed, for electronic music based on loops, it can be annoying to have out of sync notes (well I agree that on some tracks, it's cool to have a not-perfect timing that brings "life", but not on all of them).
Of course, you can always use Ableton Live's "Warp" feature to correct the timing of the notes, or alternatively record first in MIDI, MIDI quantize, and then send the quantized MIDI performance back to the synth. But having to stop playing and go to the computer is sometimes not what you would have liked.
Idea: let's build a MIDI device that takes all incoming notes arriving on MIDI IN, quantize them (i.e. align them on a grid based on sync messages, for example a 1/16 notes grid), and send them to the MIDI OUT. All of that, realtime!
Day 2: get some electronic parts
I first needed some electronic parts to do that: a breadboard, an Arduino Nano, some resistors, capacitors, an optocoupler 6N138 (very often used for MIDI circuits) that I still had in my drawers, and a small ATtiny45 chip kindly provided by the cool local Fablab team.
Then I learnt how to do a basic Arduino program (with the usual
loop functions) on an Arduino Nano. If you have a Nano clone like me, you'll need to install the drivers (CH34x_Install_Windows_v3_4.zip) to make it work.
The next step is to be able to use the Arduino Nano as a programmer to upload code on a bare ATtiny45 chip. The interesting thing is that you can remove the Nano at the end, and your code will still be running on this small 8-pin standalone 1$ chip! To do that, first open the "Arduino as ISP" sketch in Arduino IDE, and upload it to the Nano. Then connect the ATtiny45 to the Nano using this schematic, use "Programmer: Arduino as ISP", and "Upload using programmer". In real life it takes a few hours to get all these things working, but more or less that's the summary.
Then I assembled a basic well-known MIDI IN and MIDI OUT circuits, routed to the pins of the ATtiny. I wrote some test code to send MIDI messages at 31250 baud and it worked!
An other awesome thing I wasn't even expecting: this device will require no 9V battery, no AA battery, no 9V adapter... Wait, are you saying it will not be powered? The answer is: MIDI powered! The chip consumption is so small that it can be powered by the MIDI IN cable itself (inspiration here), the only component needed for this is a large-enough capacitor, something like 33 µF.
Day 3: it works, now let's make a real PCB of it
Since it works on the breadboard, I decided to learn how to make a PCB that will be eventually manufactured in China (I phoned various local electronic companies in France: nobody produces PCB locally anymore...). For this purpose, I installed Eagle software, discovered how to find components (not easy to find them in the libraries at the beginning) and to do a simple schematic. Then go in "Board" mode and use the "Autorouter" to automatically place components on the board.
A couple of hours later, I sent the board Gerber files to Seeed China who will make the PCB for the crazy price of 5$ (for 10 units, amazing!).
Day 4: work on the code, and discover the software serial madness
Decoding serial port input raw bytes into useful MIDI messages is not as easy as it seems: certain MIDI messages are 1-byte long, some other are 3-byte long, etc. so I spent some time achieveing to do that.
I then discovered that receiving and transmitting bytes on a serial port (MIDI is just serial after all) is not an easy task if you have to do it via software. But wait, why do it via software? Answer: the ATtiny45 does not feature a UART hardware serial, so it's up to the software to do it. All works well when you play only a few notes per second on the keyboard, but things are more difficult if you receive more than 10 MIDI messages per second on the MIDI IN (and this is the case: BeatClock messages used for synchronization use 24 messages per beat): the chip is lost, and the bytes read and sent are ... simply garbage! So I tested various software implementations: NewSoftSerial, NeoSWSerial, AltSoftSerial, etc. but as of today, none of them solved the problem of being able to read and transmit bytes on the serial port at the same time with an ATtiny45, at 31250 baud.
Day 5: let's test with a chip that has a real serial port
I should maybe use a chip that has a real (hardware) serial port. An option would be the ATtiny4313 (20 pins), but I don't have any.
I then tested with an ATmega328p (thanks to Julien!), taken from an Arduino Uno. It works great out-of-the-box: the hardware serial does miracles, and there is no more issues, no more grambled MIDI messages!
Now I wanted to put this ATmega328p standalone on a breadboard, but it stopped working. Reason (discovered a few hours later): this chip was internally configured to use an external crystal clock, that I did not have. So you have to modify its "fuses" to make it work with its internal clock at 8 Mhz. Working again!
Only problem: the PCB that is currently being made at the factory has a slot for a 8-pin ATtiny, and now I need to use a 28-pin ATmega, oops! I'll figure out this later, and I'll use some wires for this v0.0.1 prototype.
Day 6: do nothing
Day 7: PCBs arrive at my door
(after the week-end)
Now the parcel finally arrived, after a long trip from Shenzhen, China.
Let's assemble the components:
(It was a bit difficult to host the 28-pin chip on a PCB made for a 8-pin chip, but anyway... version 0.0.2 won't have these cables anymore).
Surprise, it works!
The "MIDI Quantizer" device is ready to be used :)
Edit: I've now done it with a 20-pin ATtiny4313, so only 1 wire is needed:
I assembled two units, one of them was working straight away, while the second seemed to have difficulties sending MIDI to some synthesizers (some synths reacted with "Illegal Data" message). I suspected the internal 8 Mhz clock to be not perfectly calibrated. So I re-uploaded the code with a internal-1 Mhz clock setting, and then it worked. Might be a good idea to add a crystal oscillator for next version of the PCB.