Shadowsocks-Qt 3.0

Happy 2018! Shadowsocks-Qt5 3.0 and libQtShadowsocks 2.0 have now been marked as stable and released!

For people who are not familiar with Shadowsocks, it is a lightweight secure SOCKS5 proxy initially developed in China to circumvent the great firewall. I’ve been developing and maintaining the Qt/C++ implementation of this protocol for quite some time. By protocol, it means you can mix and match different implementations (or so called ports in some context) of Shadowsocks. A popular setup is to use shadowsocks-libev as the server, while using the Android app or shadowsocks-windows, shadowsocks-qt5 as desktop clients.

Back to today’s business, after a long and painful period of refactoring and cleaning, I’m happy to announce that the new major update of Shadowsocks-Qt5 and libQtShadowsocks have finally come! The highlights are:

  1. Full support of Shadowsocks AEAD ciphers (requires botan >= 2.3.0)
  2. Full support of Shadowsocks SIP004 URI scheme, which is widely used by other clients for QR code
  3. Complete migration to CMake build system
  4. A compiler that supports C++14 is required (e.g. GCC >= 4.9)

Meanwhile, some of you may also notice a few changes to the project. I will no longer maintain any binary packages except for Fedora and AppImage. Right, that means not even Windows binaries are provided. I had a lot of difficulties compiling all the dependencies and linking them statically on Windows. As for Ubuntu PPA, I don’t use Ubuntu and it makes little sense for me, a non-Ubuntu user, to maintain it since I can’t even test. Time is also part of the reason why I’ve made this decision so that I can focus on coding.

Since I did mention AppImage, yes, this is an exciting new way to try out Shadowsocks-Qt5 on your Linux machines. Especially if you want to use AEAD ciphers since most Linux distributions don’t ship Botan-2, why not downloading the AppImage file and give it a go? It has bundled the latest version of Qt and Botan libraries as of writing.

Before I finish this post, I’d like to mention a few things that I probably will do later in this year (this is not a promise):

  1. Moving further away from Qt libraries in libQtShadowsocks, more and more C++11 and C++14 features will be used instead. The ultimate goal (in the far future) might be to create a “libShadowsocks++” project that doesn’t depend on Qt at all (the alternative for networking library can be asio)
  2. Finish the plug-in support proposed in SIP003
  3. Replace the dependency zbar with something more modern

Shadowsocks-Qt5 AppImage

Applications on Linux tend to be distributed by distributions, managed/packaged by distribution’s package managers. For upstream application developers, one way to ship the software to users is to create binary packages for mainstream Linux distributions. Don’t get me wrong, it is not too difficult, given we’ve now had Launchpad for Ubuntu, Copr for Fedora, OBS for OpenSUSE. Arch Linux has AUR, although that is just recipe collection.

By chance, I’ve seen Krita is shipping their software using AppImage. My attention was drawn over immediately. It looks very promising, given how many upstream apps are packaged in AppImage and how easy-to-use it is. The best part is that AppImage doesn’t require any tools (unlike flatpak which needs OS support). It basically acts similarly to the way how people ship applications on macOS, in bundles! Hence, there you go, my journey to pack Shadowsocks-Qt5 in AppImage.

Since you can easily find well documented procedures in their Wiki pages, I won’t bother logging it step by step but only a few hiccups I got. The tool I’m using is linuxdeployqt along with the vanilla AppImageKit. Both tools are distributed in AppImage format, how convenient! 🙂

As recommended, you should use a relatively old Linux distribution to make your AppImage file as compatible as possible (apps linked against newer GLIBC won’t be able to run with older GLIBC). I’ve chosen Debian Jessie as the host OS which has very similar software suite as Ubuntu Trusty does (so I can use Travis CI in the future to automate AppImage build).

One hiccup I got was a symbol error from, see this issue. After a few days Googling, I found a similar issue which points to freetype and harfbuzz themselves. So I just tried to remove and from appdir directory, and packed with appimagetool, voila it works! I have to point out that linuxdeployqt will always try to put those necessary libraries into appdir when you use it to pack AppImage. In the end, I had to replace the last step with vanilla appimagetool. In another words, what I did was

linuxdeployqt ./appdir/usr/share/applications/shadowsocks-qt5.desktop -bundle-non-qt-libs
rm -f ./appdir/usr/lib/
rm -f ./appdir/usr/lib/
appimagetool ./appdir

An experimental AppImage file has been uploaded to the releases page, please give it try, especially if your Linux distribution doesn’t have Shadowsocks-Qt5 in the repository.

qmake_qt5 macro in rpm spec

I got “Empty %files file /blah_blah_blah/debugfiles.list” errors when I package the same RPMs since I had upgraded my laptop from Fedora 23 to Fedora 24.

A quick Google redirected me into this old mail list. The hint is very important, which reads

That’s an indication that you build with “wrong” compiler flags, which don’t generate debug information in the binaries.

It then turns out there is a hidden macro %{qmake_qt5} that passes correct compiler flags and all those magic arguments. I found out this by checking out Qupzilla’s official spec file on Fedora.

I’m not 100% sure why calling qmake-qt5 directly was OK on pre-F24 systems (RHEL 7, Fedora 21 to Fedora 23). But it’s very likely that the necessary compiler flags that used to be included in global qmake.conf are now gone.

I can also confirm that this macro, %{qmake_qt5}, works on RHEL 7, Fedora 22 and Fedora 23.

Shadowsocks on RHEL 101

This post is written as a basic guide to install and setup shadowsocks server on Red Hat Enterprise Linux (or its clones such as CentOS). shadowsocks-libev is chosen as the shadowsocks port (implementation) for this guide.


Shadowsocks is a beloved lightweight secure proxy procotol that can help you bypass firewalls. It’s incredibly flexible and easy to deploy, setup, or even implement it from scratch. Shadowsocks runs on Windows, Mac, Linux, FreeBSD, Android, iOS and more! It runs on x86, ARM, MIPS and more, from PCs to routers!

The project is open-sourced and hosted on GitHub. Different implementations (shadowsocks port) have different licenses though, their features may vary, especially for non-essential features.


You don’t need to compile source code yourself. Instead, the recommended way is to install from Copr repository.

  1. Download repo from Shadowsocks Copr.
  2. Put repo file into /etc/yum.repos.d/.
  3. Execute sudo yum update and sudo yum install shadowsocks-libev in terminal.

Server Configuration

Open the configuration file /etc/shadowsocks-libev/config.json (You’ll need root priviledge for this). An example configuration is pasted below:

  • server: Server listening address
  • server_port: Server listening port
  • local_port: Local listening port (ignored by server)
  • password: Password used for encryption
  • timeout: Maximum idle time for a TCP connection
  • method: Encryption method

Start Service

  • For RHEL 6, execute sudo service shadowsocks-libev start to start.
  • For RHEL 7 or Fedora, execute sudo systemctl start shadowsocks-libev to start.

Client Configuration

There are a lot of shadowsocks clients available on all major platforms. The client’s configuration should be the same as server’s. Well, the server IP is the server’s public IP instead of

You must understand the client is effectively a local SOCKS5 proxy server that forwards data to remote shadowsocks server. In order to complete the proxy channel, you need to set applications’ SOCKS5 proxy server to the client‘s address and port.

A good news is on Android platform, shadowsocks client is more or less like a VPN (easier to setup for tech noobs). You can set it proxy the whole handset, or just proxy certain apps.

Don’t want to type that loooong and full-of-symbols password? Check the Quick Guide to use QR Code to share your configuration (Note: One-time authentication option is not included in QR Code).

Install Terminus Font as A Normal User

For old Linux distributions, TrueType Fonts (TTF) are installed into $HOME/.fonts if not installed globally. As an even older practice, bitmap fonts (usually used in xterm or urxvt) installation is slightly different.

Here is my situation:
– Red Hat Enterprise Linux 5
– No root priviledge
– System reboots every week

As you may know, those now deprecated configuration methods are the only ways on this old system. To be honest, I never installed a bitmap font before because TTF is simply much better and eye-friendlier. But if we consider the rendering speed, of course bitmap is faster in most cases.

Anyway, take Terminus as an example since it’s very popular (not my type of font). Download the latest source code from its project website and extract it. Then,

./configure --prefix=$HOME/.local
make install fontdir

Now these fonts should be installed into your home directory. Before they can be used, you need to type some commands:

xset +fp $HOME/.local/share/fonts/terminus
xset fp rehash

To preview the font, simply run xfontsel and change font family to terminus. You can also list all terminus fonts using xlsfonts | grep terminus.

You should be able to download the TTF type font of terminus, if that’s the case, you need to copy them into $HOME/.fonts directory and run fc-cache -rv to refresh the cache.

Change your terminal font to a nice one before you get your eyes blind. 🙂

Build GCC 5.2 on RHEL 6

To build GCC, we need other three components, GMP, MPC, and MPFR. And I found a lazy way to compile all of them together here. But because GMP, MPC, MPFR are compiled together with GCC, they’re certainly not installed before the new GCC is installed. So we can’t do make -k check to make a test after the compilation in this way. If you’d like to do a test, please go the traditional way, build and install them one by one seperately.

tar xf gcc-5.2.0.tar.bz2

tar xf gmp-6.0.0a.tar.xz
mv gmp-6.0.0 gcc-5.2.0/gmp

tar xf mpc-1.0.3.tar.gz
mv mpc-1.0.3 gcc-5.2.0/mpc

tar xf mpfr-3.1.3.tar.xz
mv mpfr-3.1.3 gcc-5.2.0/mpfr

mkdir gcc-5.2.0/gcc-build && cd gcc-5.2.0/gcc-build

# I don't have root privilege, so install to a subdir in my home directory
../configure --prefix=$HOME/gcc5 \
             --disable-multilib \
             --enable-languages=c,c++ \
             --enable-libstdcxx-threads \
             --enable-libstdcxx-time \
             --enable-shared \
             --enable-__cxa_atexit \
             --disable-libunwind-exceptions \
             --disable-libada \
             --host x86_64-redhat-linux-gnu \
             --build x86_64-redhat-linux-gnu \

# For clusters, you should request a compute node in slurm to do the compilation. Don't do these in head node
make -j4

make install

With --with-default-libstdcxx-abi=gcc4-compatible, we avoid recompiling all C++ libraries built using older GCC (prior to GCC 5.1). This ensures the default ABI is the old, GCC4-compatble one instead of the newly introduced CXX11 ABI. Check Configure – The GNU C++ Library for details.

Continue reading “Build GCC 5.2 on RHEL 6”

Use avconv to Convert Video Format

avconv is a utility that belongs to Libav project. Similar to its precedent ffmpeg, it supports lots of mainstream encoders and decoders. Here I just put some simple commands as a personal memo and a brief guide.

Install libav-tools via apt-get on your Debian/Ubuntu machines. Note on my Fedora laptop, there is no libav but only the original ffmpeg packages. The command-line options are fairly similar (sometimes even identical). In that case, you only need to substitute ffmpeg for avconv.

Continue reading “Use avconv to Convert Video Format”