What's new

pixelserv pixelserv - A Better One-pixel Webserver for Adblock

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

Code:
iptables -t nat -A PREROUTING --dest 10.8.10.8 -p tcp --dport 80 -j DNAT --to-dest 192.168.1.1:8080
iptables -t nat -A PREROUTING --dest 10.8.10.8 -p tcp --dport 443 -j DNAT --to-dest 192.168.1.1:8088

when using adblock 2.0, what ip should i put instead of 10.8.10.8?

10.8.10.8 (if you're not using 10.0.0.0/8 for your LAN)
 
We're very close to version Ki.

In a recent continuous run of pixelserv-tls, I accumulated a total over 3 million requests in a month. By default Linux limits process id to max 32768. That means my poor router's process id space is recycled more than 90 times during that period or 3 times per day on average. That's pixelserv alone. I have other script based daemons running which also significantly accelerates the recycling to be much faster than 3 times per day.

While it's not an issue as Linux is robust, I prefer a bit more eternity, especially in syslog where I like pixelserv to stick with one process id. Also I become less obsessed with minimal resident RAM usage (which fork() based pixelserv provides). This led to an overhaul of multiprocessing in the to-be-released version Ki.

Changes just pushed to Git with full support of pthread in pixelserv from serving requests to certificate generation. Some anecdoctal performance data. Version Ki average process time 23ms for one HTTPS request (35ms in version Kh). Plain HTTP is much faster <10ms and not compared.

Certificate generation is about 2 cert per second. Version Ki has a slight performance increase. I've seen max of 127 certificates per minute while Kh max out at 110 certs per minute.

In version Ki, using intermediate CA certificate requires extra work. Anecdotal data shows that's 1ms extra on average. So we have a very efficient approach implemented!

For people who enjoy pixelserv-tls, hope you like the improvements in version Ki. Giving it a few more days or no bugs reported I'll make a release.

(Test data done on a RT-AC56U @ 1.4GHz with a fast USB thumb drive.)
 
I was challenged offline last night on the speed-up of pthread over fork(). It was just the backdrop...but brought my attention to average processing time (tav) in pixlserv. I never seriously looked at its calculation before. I do recall during my recent long run tav seldom move a tiny bit most of the time!

Here is the original code. It's trying to calculate a moving average. It basically says this:

new average process time = old average process time + (current process time - old average process time) / tct.

where tct accumulates the number of data points used in the entire history of calculation. The 0.5 in the code is for rounding. pipe data.run_time has the current process time.

The code implements some sort of exponential moving average (but not exactly is). The factor 1/tct appears like the alpha coefficient however it's monotonically increasing. And that's the problem!

If we take the limit on tct (to infinity), the second term in the above pseudo code will tend towards zero. New average process time will be equal to old average process time. That is when you run pixelserv long enough, average process time will stuck and seldom move a bit.

Imagine tct accumulates to 1 million. Current process time need to last 1 million milli-seconds for the second term to be close to 1 and move 1 ms in the new average process time. That's insane and will never happen. The longer you run the harder to move the needle a tiny bit.

But how long is long enough to see this "stuck" effect? It doesn't require that long actually...by the fact that in the code right-hand side using floating point calculation but truncated into an integer (tav) for store on the left hand side. With trial and error, we could estimate about 100 data points will pretty much freeze the average process time at its last value. Any new data points will hardly have effect. So after the first 100 requests to pixelserv, the average process time is pretty much set in stone.

The average byte per request (avg) has the same issue.

I'm going to change both calculations to an exponential moving average with a coefficient of 1/10 for tav and 1/100 for avg. For the EMA to do well, we need floating point for persistent store but convert to integer for presentation. Will be glad to hear better ideas.
 
I didn't write the average calc - but did review it - I thought it was correct way to maintain average in integer calcs, the divisor is the count of replies? Look forward to seeing a replacement to the forked reply processes - real webservers have a pool of workers to share the replies. The fork method will no doubt lead to memory fragmentation if not leakage - but as you say all dependent on the OS to clean up when each child and its socket connections die.
 
After some tests I'm settled with a EMA with coeff 0.002 for average process time, and a EMA with coeff 0.0001 for average byte per request. Works well in accuracy and responsiveness to changes. Below are some numbers. Since we have new calculations, comparisons only meaningful on version Ki.

Plain HTTP requests: average processing time 2ms. HTTPS requests: average processing time 12ms (for Root CA cert) and 17ms (for intermediate CA cert). So it's 5ms difference in computation cost between using a Root CA and intermediate CA cert. Not 1ms as I stated in #322 but still very good. All data averaged over 10,000 requests.

Look forward to seeing a replacement to the forked reply processes - real webservers have a pool of workers to share the replies. The fork method will no doubt lead to memory fragmentation if not leakage - but as you say all dependent on the OS to clean up when each child and its socket connections die.

A pool of fixed worker threads will increase efficiency but for pixelserv to benefit it'll take some extra work. Setting up a secure session is costly. If we re-use security context, the processing time will be much closer to plain HTTP requests. Pixelserv is though acting like hundreds of thousands of webservers. We have to find an intelligent way to manage what webservers to cache with the pool of threads. Will be an interesting problem to solve. Something won't be in version Ki but definitely worth looking into beyond. :)

(Data taken on a RT-AC56U @ 1.4GHz over 886Mbps WLAN connection)
 
Code:
#!/bin/sh

ENABLED=yes
PROCS=pixelserv-tls
ARGS=""
PREARGS=""
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/opt/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

. /opt/etc/init.d/rc.func
Great to see pixelserv integrated in your adblock solution! That's about right on the router side. Just note a few things:

1. ca.crt and ca.key preferably generated with a lifetime of 10 yrs. Check if that's the default in the OpenVPN tutorial you quoted. Regardless, certificates generated automatically by pixelserv-tls have a lifetime of 10yrs. So with ca.crt 10 yrs the whole setup will last as long as that without human intervention.

2. server.crt, server.key and /jffs/etc/pixelserv.pem are not required for pixelserv-tls to operate. If you have users switching WebUI to HTTPS, then the server.crt/server.key might be re-used for the WebUI httpd. Check here for details: http://www.snbforums.com/threads/pi...ebserver-for-adblock.26114/page-9#post-252339

3. Personally I don't run WebUI over HTTPS. Responses are noticeably slower than plain HTTP. Beginning with recent stock/merlin firmwares (I forgot the exact version), WebUI httpd is no longer bound to all interfaces. Hence, you can create a virtual interface for pixelserv-tls e.g. I've been using these two lines in wan-start:
Code:
ifconfig br0:pixelserv 192.168.1.3 up
logger -t $tag "br0:pixelserv 192.168.1.3 created."

Then start pixelserv on 192.168.1.3 (that you will change in Entware's init script for pixelserv-tls), and have 192.168.1.3 in your host files.

Both #2 and #3 are fine. So pick either one where you see fit.

On the client side (MacOS/iOS/android/Windows), users will need to import ca.crt by following steps here: https://github.com/kvic-z/pixelserv-tls#import-cacrt-into-clients
Hi there,
i have installed the entware-ng version of pixelserve-tls and want to edit the init script so it runs on a virtual interface. is the right script the entware-ng.arm/etc/init.d/S80pixelserv-tls one? The routers ip is 192.168.2.1 so does the virtual interface need to be 192.168.2.3? How do i go about this...do i edit the ARGS line . Or am i barking up the wrong are and need an entire new start script?

Thanks
 
Hi,

is the right script the entware-ng.arm/etc/init.d/S80pixelserv-tls one?

I believe that's the exact name of the script that launches pixelserv-tls in Entware-ng.

The routers ip is 192.168.2.1 so does the virtual interface need to be 192.168.2.3? How do i go about this...do i edit the ARGS line . Or am i barking up the wrong are and need an entire new start script?

You're on the right track. I wrote a tutorial for you and other new users. Read here:

https://github.com/kvic-z/pixelserv-tls/wiki/How-to-best-run-pixelserv-tls-on-Asuswrt-Merlin

Hope it helps.
 
Hi,



I believe that's the exact name of the script that launches pixelserv-tls in Entware-ng.



You're on the right track. I wrote a tutorial for you and other new users. Read here:

https://github.com/kvic-z/pixelserv-tls/wiki/How-to-best-run-pixelserv-tls-on-Asuswrt-Merlin

Hope it helps.
Great tutorial thanks!.... using it with AB-solution ... seems to be working fine.
Code:
Sep 12 13:26:32 pixelserv[885]: pixelserv-tls version: V35.HZ12.Kh compiled: Aug 19 2016 10:51:54 options: 192.168.2.3
Sep 12 13:26:32 pixelserv[885]: Listening on :192.168.2.3:80
Sep 12 13:26:32 pixelserv[885]: Listening on :192.168.2.3:443
Code:
Sep 12 13:38:53 pixelserv[1012]: pagead2.googlesyndication.com _.googlesyndication.com missing
Sep 12 13:38:54 pixelserv[1019]: pagead2.googlesyndication.com _.googlesyndication.com missing
Sep 12 13:38:54 pixelserv[1014]: cert _.googlesyndication.com generated and saved
Sep 12 13:41:08 pixelserv[1052]: appload.ingest.crittercism.com _.ingest.crittercism.com missing
Sep 12 13:41:09 pixelserv[1053]: cert _.ingest.crittercism.com generated and saved
 
something new about pixelserv? we still need change to https on router side?
 
something new about pixelserv? we still need change to https on router side?

There will be a refresh to HTML servstats page in version Ki. New layout, more logical ordering of items and self-explanatory notes to each item.

SS.png

edit: replaced with the correct screenshot.
 
Last edited:
Hi Kvic
Will new versions of Pixelserv-tls be available via Entware, and if so, what steps will be needed to do the upgrade? . I believe that Entware will simply replace the old version rather than modifying it. Will the certs all have to be regenerated?
 
After some tests I'm settled with a EMA with coeff 0.002 for average process time, and a EMA with coeff 0.0001 for average byte per request. Works well in accuracy and responsiveness to changes.

The above coeff. for average byte per request (avg) is visually more pleasing. But to be statistically consistent I change back to 0.002, same as average processing time (tav).

The following chart shows the weight curve of the EMA that the new version will use for avg and tav meters. Only shown the most recent 1000 sample points. New points receive higher weight, with the most recent weighing 0.002. All points beyond the 1000 data points of course are also accounted for in EMA albeit with an diminishing weight towards 0.

With the coefficient we pick, the most recent 1000 data points represent 86% weight in the calculated value. In practice, about 5 to 7 successive drop or increase will move the needle by 1ms on tav, and larger steps for avg (hence the part of less visually pleasing but still very good imho).

EMA.png

(This feature will be in the coming version Ki)
 
Hi Kvic
Will new versions of Pixelserv-tls be available via Entware, and if so, what steps will be needed to do the upgrade? . I believe that Entware will simply replace the old version rather than modifying it. Will the certs all have to be regenerated?

Entware-ng updates their repository on regular basis. Hence, you might have to wait a bit after the new version is released (which not yet atm). If recall correctly the command is "opkg upgrade pixelserv-tls"

Exisiting certificates are forward compatible with new versions. If you want you can remove all generated certificates anytime, they'll be re-generated on the fly when pixelserv sees a missing certificate on next request.

Personally I don't flush certificates. Old timestamps on those certificates are pleasing to look at in a few years time. lol
 
Hi,

I seem to have an interesting issue.

It seems that if I have an openvpn server configured on my router and install and enable pixelserv-tails, following this guide to install/configure:

https://github.com/kvic-z/pixelserv-tls/wiki/How-to-best-run-pixelserv-tls-on-Asuswrt-Merlin

And this guide to create my ca keys:

https://github.com/kvic-z/pixelserv-tls#pixelserv-tls

I can no longer connected to my openvpn server. I need to uninstall pixelServ for me to re-connect to my vpn.
I have pixelserv-tls running on my 87U, with two openvpn servers running. I connected to both of them today without issue. My pixelserv is listening on an IP other than the router's. I followed both those guides. So it does work for me. Just a data point.

I have had some issues with one or the other or both of the servers no longer running, but I ascribe that to other things. I'm on .62a.
 
By default pixelserv listens on ports 80 and 443, but you can change this from the call parameters BUT you would also need iptables diverts because browsers using dns based blocklist will direct requests to these common ports for http and https. I add alternate http ports for testing/ one particluar site that seemed to trying to get around my pixelserv!

Code:
pixelserv-tls version: V35.HZ12.Kh compiled: May 11 2016 15:13:54 options: 192.168.66.254 -p 80 -p 81 -p 8080 -p 8081 -k 443 -o 2

Yes still not got latest version for my mips router!
 
It would be nice for the pixelserv to bind only on my virtual IP (192.168.1.3) and not on all ips.

oh well...

Put 192.168.1.3 in ARGS="". Will only bind to that ip.
 
To install .ki on my 87U, do I just copy the version in the /arm folder to /opt/bin? .ki is about a MB in size, while .kh looks to be 35kb.
 
To install .ki on my 87U, do I just copy the version in the /arm folder to /opt/bin? .ki is about a MB in size, while .kh looks to be 35kb.

I would recommend doing this way:
1. mkdir -p /jffs/bin
2. cp <the binary pixelserv-tls> /jffs/bin
3. Change procs in launch script to PROCS="/jffs/bin/pixelserv-tls"


The two binaries (one for arm7 and one for mips) are statically linked image. They include everything (e.g. used functions from openssl, pthread, glibc etc). Think of it like self contained binary image. It's unlike dynamically linked binary which links to openssl, glibc, pthread libraries only when run. hence, bigger in size.

Someone PM'ed me and requested for binaries. Waiting for Entware will be long for him/her. So...static binaries are easiest for installation by end users, and quick for me to prepare too.
 
Got it. Why in /jffs instead of on the entware thumbdrive?
 
Got it. Why in /jffs instead of on the entware thumbdrive?

Personal preference only. I'm always using a statically linked pixelserv-tls placed in /jffs/bin.

Usually I would avoid overwriting files/binaries installed by a package manager. If we have to place under Entware thumb drive, we probably should put user installation under /opt/local/bin...in Unix fashion.

:)
 

Similar threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top