Skip to main content

Posts

Showing posts from 2022

Thoughts on Herb Sutter's cppfront

Recently I learned about cppfront , which is an experimental new syntax for C++ by Herb Sutter. It was nicely explained in CppCon, and I really enjoyed watching the video . Roughly I'd view it as Rust with C++ interop. It's kind of some syntax sugar, preprocessor or a dialect. It has also enforced style guide or annotations that are compiler-aware. I like it mostly, I feel excited.  And let me try to explain in a logic way. The Syntax I don't like it, nor do I hate it. I asked myself, do I not like it, just because I am not familar with it? The answer is yes. So it's my problem, not cpp2's. It didn't took me too much time to get myself comfortable (but not fluent) with Rust, so I think cpp2 won't be a problem. Comparing with Rust I got this several times while reading the docs or watching the video:  If something is bad, let's remove it from the language instead of keeping teaching "don't do this, don't do that". Examples: NULL, union, ...

清理Ubuntu软件包

我的小服务器上一直装了个Ubuntu Desktop,不过安装之后一直没用过GUI,而且各种依赖的包有时也挺烦人的,比如gvfs和tracker自带的systemd user service,我还得手动给若干用户禁用掉。 本来我是想着留个Desktop,万一紧急情况可以上网查查命令。不过有网的话,最差情况我应该也能临时装一个X和浏览器,估计问题不太大。 于是我决定把Ubuntu Desktop换成Ubuntu Server,主要还是把gnome的包都删了。 一番折腾以后,安装包的数量从大约1800降到了800以下。舒服!

Moving Items Along Bezier Curves with CSS Animation (Part 2: Time Warp)

This is a follow-up of my earlier article.  I realized that there is another way of achieving the same effect. This article has lots of nice examples and explanations, the basic idea is to make very simple @keyframe rules, usually just a linear movement, then use timing function to distort the time, such that the motion path becomes the desired curve. I'd like to call it the "time warp" hack. Demo See the Pen Interactive cubic Bezier curve + CSS animation by Lu Wang ( @coolwanglu ) on CodePen . How does it work? Recall that a cubic Bezier curve is defined by this formula : \[B(t) = (1-t)^3P_0+3(1-t)^2tP_1+3(1-t)t^2P_2+t^3P_3,\ 0 \le t \le 1.\] In the 2D case, \(B(t)\) has two coordinates, \(x(t)\) and \(y(t)\). Define \(x_i\) to the be x coordinate of \(P_i\), then we have: \[x(t) = (1-t)^3x_0+3(1-t)^2tx_1+3(1-t)t^2x_2+t^3x_3,\ 0 \le t \le 1.\] So, for our animated element, we want to make sure that the x coordiante (i.e. the "left" CSS property) is \(...

Restricting Network Access of Processes

I recently read this article , which talks about restricting (proactive) internet access of a process. It is easy to completely disable internet/network access, by throwing a process into a new private network namespace. I think all popular sandboxing tools support it nowadays: unshare -n bwrap --unshare-net systemd.service has PrivateNetwork=yes docker has internal network But the trickier, and more realistic scenario is: [Inbound] The process needs to listen one or more ports, and/or [Outbound] The process needs to access one or more specific IP address/domain I can think of a few options. Option 1: Firewall Rules Both iptables and nftables support filter packets by uid and gid. So the steps are clear: Run the process with a dedicate uid and/or gid Filter packets in the firewall If needs, regularly query DNS and update the allowed set of IP addresses. This is somehow similar to reresolve-dns.sh from WireGuard. This option is not very complicated, and I think the overhead is low....

Migrating from iptables to nftables

nftables has been enabled by default in latest Ubuntu and Debian, but not fully supported by Docker. I've been hestitating about migrating from iptables to nftables, but managed to do it today. Here are my thoughts. Scripting nftables The syntax of iptables and nftables are different, but not that different, both are more or less human readable. However, nftables is clearly more friendly for scripting. I spent quite some time in a python script to generate a iptables rule set, and I was worried that I need lots of time migrating the script. Aftering studying the syntax of nftables, I realized that I could just write /etc/nftables.conf directly.  In the conf file I can manage tables and chains in a structured way. I'm free to use indentations and new lines, and I no longer need to write "-I CHAIN" for every rule. Besides, I can group similar rules (e.g. same rule for different tcp ports) easily, and I can define variables and reuse them.  Eventually I was able to write...

Migrating to Rootless Docker

 There are three ways of running Docker: Privileged: dockerd run with root, container root = host root Unprivileged: dockerd run with root, container root = mapped user Rootless: dockerd run with some user, container root = some user I've been hestitating between Unprivileged and Rootless. On one hand, rootless sounds like a great idea; on the other hand, some considers unprivileged user namespace as a security risk . Today I decided to migrate all my unprivileged containers to rootless ones. I had to enable unprivileged user namespace for a rootless LXC container anyways. A Cryptic Issue The migration is overall smooth, except for a cryptic issue: sometimes DNS does not work inside the container. The symptom is rather unusual: curl works but apt-get does not work. For quite a while I'd thought that apt-get uses some special DNS mechanism. After some debugging, especially comparing files /etc/ between a unprivileged container and a rootless container, I realized that non-root u...

Moving Items Along Bezier Curves with CSS Animation (Part 1: Constructions)

TLDR: This article is NOT about cubic-bezier(), and it is not about layered CSS animations (for X and Y axes respectively). It is about carefully crafted combined animation, that moves an element along any quadratic/cubic Bezier curve. UPDATE: Here's the link to part 2 . Following my previous post , I continued investigating competing CSS animations, which are two or more CSS animations affecting the same property. I observed that two animations may "compete". In the following example, the box has two simple linear animations, move1 and move2. It turns out the box actually moves along a curved path: See the Pen CSS Bezier Path by Lu Wang ( @coolwanglu ) on CodePen . So clearly it must be the combined effects from both animations. Note that in move2, the `from` keyframe was not specified. It'd look like this if it is specified: See the Pen For Blog 2022-08-02 by Lu Wang ( @coolwanglu ) on CodePen . In this case, it seems only the second animation take...

Studying CSS Animation State and Multiple (Competing) Animations

[2022-08-04 Update] Most of my observations seems confirmed in the CSS animation spec . I stumped upon this youtube video . Then after some discussion with colleages,  I was really into CSS-only projects. Of course I'd start with a rotating cube: See the Pen CSS 3d Animation Test by Lu Wang ( @coolwanglu ) on CodePen . Then I built this CSS-only first person (rail) shooter: See the Pen CSS-Only Wolfenstein by Lu Wang ( @coolwanglu ) on CodePen . It was lots of fun. Especially I learned about the checkbox hack .  However there were two problems that took me long to solve. 1. Move from in the middle of an animation The desired effect is: An element is moving from point A to point B. If something is clicked, the element should move from its current state (somewhere between A and B, in the middle of the animation/transition) to another point C. This is for the last hit of the boss, the boss is fastly moving. I'd like the boss to slowly move to the center if being...

Setting up sslh as transparent proxy for a remote container

 I have an NGINX server that is publicly accessible. It has been deployed in the following manner: Machine A Port forwarding with socat: localhost:4443 ==>  0.0.0.0:443 Machine B Running NGINX in a Docker container Port forwarding by Docker: <container_ip>:443 ==> localhost:4443 Port forwarding by SSH to Machine A: localhost(B):4443 ==> localhost(A):4443 This in general works. Machine A is published to my domain, and the traffic to 443 is forwarded to NGINX in a few hops. However there is a problem: the NGINX server never sees the real IP of the client, so it is impossible to depoly fail2ban or other IP address based tools. So I wanted to fix it. Step 1: VPN The first step is to connect machine A and B with a VPN. I feel that it would also work without it, but the iptables rules could be more tricky.  WireGuard is my choice. I made a simple setup: Machine A has IP: 10.0.0.2/24 Machine B has IP: 10.0.0.1/24 On both machines, the interface is called wg0, Allo...

Home Server Tinkering

Weeks ago I  purchased a secondhand machine. Since then I have been tinkering this little box. The Perfect Media Server  site is a good place to start with. Arch Linux Wiki is my go-to learnning resource, even though I use Ubuntu. Filesystem I'd be super paranoid and careful, as this is my first time manually configuring a disk array. Basically my optoins include: ZFS btrfs Snapraid (or even combnied ZFS/btrfs) Unraid My considerations include: Data integrety, which is the most important. Maintenance. I want everything easy to set up and maintain. Popularity. There will be more doc/tutorial/discussions if the technology is more popular. Eventually I decided to use ZFS with raidz2 on 4 disks.  I also took this chance to learn configuring disk encryption. I decided to use LUKS beneath ZFS. I could have just used ZFS's built-in encryption, but I thought LUKS is fun to learn. It really was. The commands are way more user-friendly that I had expected. Hardening SSH Most popula...

Fix broken sudoers files

Lesson learned today: An invalid sudoers file can break the sudo command, which in turn prevent the sudoers file from being edited via sudo.  The good practice is to always use visudo to modify sudoers file. In my case I needed to modify a file inside /etc/sudoers.d, where I should have used `visudo -f`. To recover from invalid sudoers files, it is possible to run `pkexec bash` to gain root access. However I got an error "polkit-agent-helper-1: error response to PolicyKit daemon: GDBus.Error:org.freedesktop.PolicyKit1.Error.Failed: No session for cookie" Solution to this error: Source: https://github.com/NixOS/nixpkgs/issues/18012#issuecomment-335350903 - Open two terminals. (tmux also works) - In terminal #1, get PID by running `echo $$` - In terminal #2, run `pkttyagent --process <PID>` - In terminal #1, run `pkexec bash`

On Data Backup

Around 2013, every year I'd burn all my important data into a single DVD, that is 4.7GB. Nowadays I have ~5TB data, and I don't even bother optimizing 5GB data. Background I realized that it is the time to consider backup. I guess I have seen enough signs. The NAS shows that the disks are quite full. I just happened to see article and videos about data backup. I found corrupted data in my old DVDs. I realized that most of my important data are not properly backed up. I have a few scripts that manage different files, which might contains bugs. The goal is to have good coverage under acceptable cost. The Plan All my data are categorized into 4 classes. Class 1: Most Important + Frequently Accessed Rougly ~50GB in total. Average file size is ~5MB.  Examples include official documents, my artworks and source code. The plan: sync into multpile locations to maximize robustness. Sometimes I chooes a smaller subset when I don't have enough free space. In case some copies are down/...