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!

I'm not sure if HunterZ is on this forum. mstombs, one of the two earlier authors, is here. :)

Yes, I released the first 35 versions (I did have but never finished a V36!) , mainly on linksysinfo, but others on dd-wrt and a special version incorparated in RouterTech ADSL router firmware while I learnt how to program in C, finally HZ has merged other forks (such as indirect link diversion https://github.com/h0tw1r3/pixelserv), made a number of important bug fixes and improvements and put it on GitHub while released 12 versions explaining HZ12 (and many interim betas),

https://github.com/HunterZ/pixelserv

He has already merged in support for RPi, and I'm sure watching this thread while his focus is probably more on the Tomato adblock script (with web interface) and pixeleserv binaries. Over there they are yet to be convinced about the extra https handling, but its great to have open source collaborative effort and I'm sure those who know how to 'git' can compare/contrast and improve the version in this thread published here:-

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

and I see there are a few other forks on git hub already.

There was another interesting version that I didn't see the source code for that logged all requests to a mysql database, interesting stats from that no doubt. There is room for improvement in indirect advert link handling I know it doesn't always work...
 
Last edited:
As mentioned in #21, I had a set of scripts automating certs generation on PC. Last night I adapted and cleaned up the scripts to run on AC56U. Set up a cron job for it. It works pleasantly well. Now everything automatic..lol. The past few days have accumulated over 100 unique https ad domains in my lan/vpn.

Personally I find it's sufficiently functional. I was curious how openssl handle the same thing in APIs. was also thinking any additional benefit if convert process into thread. If I'm going to switch, why not start with a thread that generate missing certs on the fly...the thought put aside in #15? Perhaps I'll give it a try on another night..

1743970571.log.optimizely.com
ad.atdmt.com
ad.au.doubleclick.net
ad.doubleclick.net
ads.yahoo.com
analytics.twitter.com
api.pubnative.net
assets.customer.io
bat.bing.com
bs.serving-sys.com
by.uservoice.com
c.amazon-adsystem.com
c.bing.com
c1.microsoft.com
cdn.boomtrain.com
cdn.mxpnl.com
cdn.segment.io
cdn.siftscience.com
collector.githubapp.com
config-ltvp.inmobi.com
counter.yadro.ru
csc.beap.bc.yahoo.com
d31qbv1cthcecs.cloudfront.net
data.flurry.com
dev.visualwebsiteoptimizer.com
doubleclick.net
e-ltvp.inmobi.com
e.crashlytics.com
fbcdn-creative-a.akamaihd.net
fe2.update.microsoft.com
geo.query.yahoo.com
geo.yahoo.com
glitter.services.disqus.com
global.adserver.yahoo.com
googleads.g.doubleclick.net
gwa.lphbs.com
gwb.lphbs.com
hk-cm.ysm.yahoo.com
i1.services.social.microsoft.com
js-agent.newrelic.com
log.mmstat.com
lptag.liveperson.net
m.optout.ziffdavis.com
m.webtrends.com
media.go2speed.org
microsoftsto.112.2o7.net
munchkin.marketo.net
oca.telemetry.microsoft.com
ocos-office365-s2s.msedge.net
ots.optimize.webtrends.com
p.tanx.com
pagead2.googleadservices.com
pagead2.googlesyndication.com
partner.shareaholic.com
pixel.facebook.com
pixel.quantserve.com
pixel.redditmedia.com
pixel.wp.com
pubads.g.doubleclick.net
referrer.disqus.com
reports.crashlytics.com
s-v6exp1-ds.metric.gstatic.com
s.po.st
s.skimresources.com
s7.addthis.com
sb.scorecardresearch.com
sdkm.w.inmobi.com
secure-us.imrworldwide.com
secure.gaug.es
secure.quantserve.com
securemetrics.apple.com
servedby.flashtalking.com
settings-win.data.microsoft.com
settings.crashlytics.com
shareaholic.com
snap.snapmobile.asia
sqm.telemetry.microsoft.com
ssl.google-analytics.com
static.adzerk.net
static.chartbeat.com
static.hotjar.com
stats.g.doubleclick.net
stats.wp.com
sync.liverail.com
tags.bkrtx.com
telecommand.telemetry.microsoft.com
trends.revcontent.com
trk.kissmetrics.com
trk.vidible.tv
v10.vortex-win.data.microsoft.com
view.atdmt.com
vortex.data.microsoft.com
watson.telemetry.microsoft.com
widgets.outbrain.com
wprp.zemanta.com
www.assoc-amazon.com
www.doubleclick.net
www.google-analytics.com
www.googletagmanager.com
www.googletagservices.com
www.gravatar.com
www.ojrq.net
y3.analytics.yahoo.com
 
Unless you have changed this - pixelserv .c forks a new process for every reply, so time can be taken to close the connection with timeout without stalling the main thread. Is a router powerful enough to generate a new certificate 'on the fly' before replying? - If not it could revert to old style reply then do the generation before dying. A dedicate process would avoid multiple child processes generating the same cert I guess. Real webservers have a finite number of sub-processes with inter process communication, and don't rely on the OS for creating new and clearing up old all the time.
 
I didn't change the child process fork. It's same as before a new child for every reply. I was thinking of switching this to a new thread for every reply. Perhaps keep it on re-visit list for now.

I experimented with pthread and "on-the-fly" cert gen. Threads and inter-process communication were quick to get it running. The cert gen is interesting..and eventually get it to work. A prototype works on my PC Linux. Has yet to make it work on my AC56U. It spawns process instead of thread. Other than that cert gen actually works. Need to look into it on another day.

At the moment the design is one dedicated thread for cert gen. Many child processes can feed cert gen requests to it. It becomes a classical many-to-one producer/consumer problem.

I recognise the forum owner is a bit anxious about adblock. I'm thinking if we could add a whitelist feature. Say if it's referred by a certain domain, pixelserv will redirect to the actual ad server. Seems this requires pixelserv acting like a proxy. Not sure if this will add a large chunk of additional resources. Nor I know if there is a simpler way to accomplish the same. But this will be another unique feature to sustain its existence..

Thoughts?
 
I recognise the forum owner is a bit anxious about adblock. I'm thinking if we could add a whitelist feature. Say if it's referred by a certain domain, pixelserv will redirect to the actual ad server.

It's business - the SNB site is ad-powered...

unicorn farts not withstanding - blocking ads takes away revenue from the site operators, so white-listing is a good idea..
 
Whitelisting nothing to do with pixelserv, the diversion to the pixelserv IP is by dnsmasq and any adblock script there. Once the dns is poisoned all pixelserv can do is make the browser give up quickly! I can tell you that if you only use the small pgl.yoyo script and turn off adblockplus for this site you do get some unobtrusive ads here.
 
I know a few ways that can allow ad to be served even if dnsmasq based adblock in place. But here we perhaps not interested in methods using existing tools. More a focus on how pixelserv could make it possible. For adblock purpose, dnsmasq is dumb, pixelserv could act with a bit more intelligence. mstombs is right about current functionality. I think the challenge is to get it implemented in the simplest way and with minimal additional resource. We don't want to get one pixel bloated into a gigantic pic... I have a look at http 302 redirect. Not sure if this could be used for whitelist purpose.

Back to on-the-fly cert gen. To my surprise, Asuswrt is more crap than I thought. Its foundation is so dated. Hope someone will prove it wrong as I'm running out of ideas. I was having issue with pthread on Assuwrt. I think it doesn't support Native Posix Thread Library (or simply the real pthread). All test evidence I collected points to no native pthread. I thought I did the coding wrong but turned out not. It's Asuswrt, more specifically the uClibc it uses. I thought the firmware is already on uClibc 0.9.32 or newer (can anyone confirm what uClibc version it's?) but seems not. Funny is that linux kernel 2.16 is capable of native pthread but crippled by an ancient version of uClibc? I'm fine with older pthread if only looks not so nice on top. But no..this old uClibc has bugs when daemon() is mixed with pthread_create(). So much so that I gave up and scrapped the idea for pthread. I wonder how Asus implements its own applications with best possible quality without pthread. It's 2015.

I took one step back, and used fork(). On a second thought, might not be a bad thing. This gives broader compatibility of pixelserv across old and new routers. So now we have two processes all time. The main process uses ~300KiB RAM . The child process generates missing https certs and uses 100KiB RAM. These are the idle state numbers. Both will spawn off transient processes to do not so heavy lifting.

Cert gen does not require much resource. Pixelserv on my AC56U takes about 400ms on average to generate one cert (all overhead included). We could make it faster. But I chose to minimise idle state RAM usage over speed. We won't be generating certs day and night. But surely our routers will be happy to run something more interesting anytime. I also leave one option open so that cert gen requests can be fed from an external script. Just in case, someone wants to pre-generate a bunch of certs. She won't need to go back to EasyRSA scripts but simply feed a list of domains into the child process. Some might like this touch.. (one reason I prefer Unix way to one Microsoft way)
 
can anyone confirm what uClibc version it's?

The asuswrt uclibc is built as part of the toolchain - source and patched build scripts from openwrt via tomatousb, for mips routers its either 0.9.29 or 0.9.30.1 with many patches, some clearly affect pthreads

https://github.com/RMerl/asuswrt-merlin/tree/master/toolchain/toolchain/uClibc/config
https://github.com/RMerl/asuswrt-merlin/tree/master/toolchain/toolchain/uClibc/patches/0.9.30.1

It is not unusual for userspace apps to be built with a later gcc than the kernel...

Most apps seem to be plain C (20th century version?), and it can be tricky to get anything C++ to build.

ARM routers have updated versions uclibc seems to be 0.9.32.1, but I don't see the source or build tools so likely many patches too. Entware has newer versions of everything.
 
Last edited:
Thanks for the pointer. There are a few places with toolchain. I'm speculating the above one is for MIPS platform. There is another one in src-t-6.x.4708. That one may be for ARM. So indeed MIPS won't have proper support for pthread. For ARM, people would expect it should. I just re-built a test program again, still the same. I'm speculating it's a mis-configuration by Asuswrt/Merlin in linux kernel+uClibc for ARM? I recall seeing bunch of WRS processes which could be better served with threads (or perhaps indeed coded as pthread...but due to with intention or not running on an older thread model). I think Asus shall look into the pthread issue. It's plain silly..

New version for Pixelserv: V35.HZ12.Kd

For people interested in pixelserv /w https support, now it can automatically generate certs.. on the fly. We only need the first two bullet points from #40 and place the three ca.* file under /opt/var/cache/pixelserv. Or the directory you override with pixelserv cmd line option "-z". From there on everything will be automatic.
 
Yes, I recognize those MIPS toolchain sources from tomatousb, which are compilable even with 64-bit linux, and I once fixed a uclibc timezone bug that was only present for a few days, but won't recurr for another 5 years....

It seems Netgear have released Broadcom ARM toolchain sources which look very similar, see

https://github.com/jeremyd2019/hndtools-arm-linux-uclibc

I suspect it is likely Asus have kept with userspace options that work with mips and arm (and ralink?), but when they drop the older mips ...
 
Last edited:
Yes, I recognize those toolchain sources from tomatousb, which are compilable even with 64-bit linux, and I once fixed a uclibc timezone bug that was only present for a few days, but won't recurr for another 5 years....

It seems Netgear have released Broadcom ARM toolchain sources which look very similar, see

https://github.com/jeremyd2019/hndtools-arm-linux-uclibc

I suspect it is likely asus have kept with userspace options that work with mips and arm (and ralink?), but when they drop the older mips ...

Asus includes the ARM toolchain in their GPL release, however I don't want to add another number of megabytes of files to the repo, which would slow it down even further. You can get their buildroot tarball inside their official GPL releases.
 
Asus includes the ARM toolchain in their GPL release, however I don't want to add another number of megabytes of files to the repo, which would slow it down even further. You can get their buildroot tarball inside their official GPL releases.
Thanks, that partly explains why their GPL release now up to 750MB, I assumed they just hadn't use the best tar parameters. I also assumed (incorrectly!) that your Github repository was a superset, filling inadvertent gaps in specific router downloads.
But I have just checked - the latest 87U Asus GPL just contains the old MIPS toolchain sources
The Netgear GPL R6250-V1.0.0.62_with_toolchain_source.zip contains buildroot-2012.02.tar.bz2 which seems to match the source referenced in
https://github.com/RMerl/asuswrt-me.../bin/arm-brcm-linux-uclibcgnueabi-gccbug#L352

The buildroot contains the patch for the DST bug in mips toolchain I observed years ago
uClibc-0.9.31.1-fix-daylight-saving-time-handling.patch
 
Last edited:
Ok, I also downloaded the latest Asus GPL code for AC56U. I can confirm uClibc 0.9.32 is used for ARM. Native pthread is not enabled. Old/ancient threading model is used instead.

Checked Netgear uClibc for ARM from #50. Same thing. So I doubt it's a decision made by Asus. Probably vendors take what's fed by brcm. That's sad. Anyone wants to enable native pthread for ARM?

Or take the shortcut to install Entware? For media fanatics, now there is a very good reason to run miniDLNA from Entware..

EDIT:

Since Entware caters to multiple platforms and to be generally usable for the largest number of users possible, usually the same app uses more resources than that comes with the firmware. Might well be the case for minidlna.
 
Last edited:
Thanks for the pointer. There are a few places with toolchain. I'm speculating the above one is for MIPS platform. There is another one in src-t-6.x.4708. That one may be for ARM. So indeed MIPS won't have proper support for pthread. For ARM, people would expect it should. I just re-built a test program again, still the same. I'm speculating it's a mis-configuration by Asuswrt/Merlin in linux kernel+uClibc for ARM? I recall seeing bunch of WRS processes which could be better served with threads (or perhaps indeed coded as pthread...but due to with intention or not running on an older thread model). I think Asus shall look into the pthread issue. It's plain silly..

New version for Pixelserv: V35.HZ12.Kd

For people interested in pixelserv /w https support, now it can automatically generate certs.. on the fly. We only need the first two bullet points from #40 and place the three ca.* file under /opt/var/cache/pixelserv. Or the directory you override with pixelserv cmd line option "-z". From there on everything will be automatic.
Any chance of you starting to compile x86/x64 binaries? I'd love to visualize this on something small like TinyCoreLinux. Been hassling with compiling it for a couple hours and I'm having no success.
 
It should be relatively straightforward to compile for x86/x64 we looked at this for an earlier version

http://www.snbforums.com/threads/pi...ebserver-for-adblock.26114/page-2#post-208912

I don't know about TinyCoreLinux, but it would be best to compile natively to avoid library dependencies - but you do need the appropriate dev package headers. When it compiles it will be smallest quickest package build of any! I have a 32-bit Ubuntu under virtualbox somewhere I'll try with the latest...
 
Last edited:
Any chance of you starting to compile x86/x64 binaries? I'd love to visualize this on something small like TinyCoreLinux. Been hassling with compiling it for a couple hours and I'm having no success.

Glad to hear new interest in this! I've uploaded x86-64 aka amd64 binary for the latest version: V35.HZ12.Kf

I always built for amd64 during development. So it's easy for me to include the binary. I never attempt 32-bit x86. You may have to wait for mstombs for that as he successfully built before.

Summary of changes since version Kd
  • New HTML servstats
  • Added Entware-arm build with native pthread support
  • Added pthread support for cert gen
  • Set proper permission for /tmp/pixelcerts. No permission denied for non-root
  • Fixed memory leak in cert gen.
 
Hi, is there a step by step guide? Im currently using lonecoders combined hosts and its working well , but Im willing to test this, my DSL is slow and high in latency, I got a 66U with entware and last merlin firmware. Thanks
 
Hi, is there a step by step guide? Im currently using lonecoders combined hosts and its working well , but Im willing to test this, my DSL is slow and high in latency, I got a 66U with entware and last merlin firmware. Thanks

A step by step guide will take much time to draft and make it near faultless...so personally I don't plan to do so. However, I can sketch high-level steps (without going into exact details upfront):
  1. Move your WebUI to run on HTTPS with port 8443. This will free up port 80 for pixelserv.
  2. Rename ip address of a few select entries (e.g. doubleclick.net is a good candidate; t's for pilot test) in your block list to point to your.router.ip.address. Restart dnsmasq.
  3. Start pixelserv from command line with "/path/to/pixelserv your.router.ip.address"
  4. Test with "http://your.router.ip.address/servstats". This will show you a page similar to the running stats in post #1.
  5. Test with "http://doubleclick.net/" . This will show you a blank page without error.
  6. Up to this point everything looks good then. Proceed to setup auto run of pixelserv on startup by deploying the init.d script in post #1.
  7. Then modify your dnsmasq block list scripts to use your.router.ip.address instead of 0.0.0.0.
  8. Follow the guide in post #1 to setup a CA cert. After that certs for ad domain will be auto generated by pixelserv.
  9. Up to this point, I believe you shall be all set.
I hope you can work out the details. Feel free to ask us if you run into errors.
 
...I never attempt 32-bit x86. You may have to wait for mstombs for that as he successfully built before.

To build X86 natively on a 32-bit Ubuntu I had to edit the x86 section of the Makefile as follows

Code:
x86: ARCH = x86
x86: LDFLAGS += -lpthread
x86: CFLAGS += -pthread -DUSE_PTHREAD
x86: printver dist
    @echo "=== Building x86 ==="
    $(CC32) $(CFLAGS_D) $(LDFLAGS_D) $(OPTS) $(SRCS) -o dist/$(DISTNAME).$@.debug.dynamic $(SHAREDLIB)
    $(CC32) $(CFLAGS_P) $(LDFLAGS_P) $(OPTS) $(SRCS) -o dist/$(DISTNAME).$@.performance.dynamic $(SHAREDLIB)
    $(CC32) $(CFLAGS_D) -static $(LDFLAGS_D) $(OPTS) $(SRCS) -o dist/$(DISTNAME).$@.debug.static $(SHAREDLIB)
    $(CC32) $(CFLAGS_P) -static $(LDFLAGS_P) $(OPTS) $(SRCS) -o dist/$(DISTNAME).$@.performance.static $(SHAREDLIB)
#    $(STRIP) dist/$(DISTNAME).$@.performance.*
#    $(UPX) dist/$(DISTNAME).$@.performance.*
    rm -f dist/$(DISTNAME).$(PVERSION).$@.zip
    $(PCMD) dist/$(DISTNAME).$(PVERSION).$@.zip $(PFILES)

I'm not sure what the ARCH define does, it is actually used in the Makefile before defined so good job it is correct by default! I guess Makefile will be broken if cross compiling the x86 version on AMD64. So does that mean the other versions all use the system library headers for ssl? STRIP still breaks the dynamic build (noted in the Makefile), so commented out, UPX works but is slow and not really needed! Too many warnings for my like, for example

Code:
certs.c: In function ‘generate_cert’:
certs.c:55:5: warning: implicit declaration of function ‘asprintf’ [-Wimplicit-function-declaration]
     asprintf(&fname, "%s/%s", pem_dir, pem_fn);

which seems to be a distro fault, it appears <stdio.h> needs _GNU_SOURCE to be defined to a value, not just defined, but attempting to fix this causes lots more messages about macro redefinition...

Output files are

Code:
VirtualBox:/media/sf_VMShare/pixelserv-tls-35.HZ12.Kf$ ls -laF dist
total 5632
drwxrwx--- 1 root vboxsf    4096 Nov 18 23:13 ./
drwxrwx--- 1 root vboxsf    4096 Nov 18 23:00 ../
-rwxrwx--- 1 root vboxsf  926900 Nov 18 23:13 pixelserv.V35.HZ12.Kf.x86.zip*
-rwxrwx--- 1 root vboxsf   98592 Nov 18 23:13 pixelserv.x86.debug.dynamic*
-rwxrwx--- 1 root vboxsf 2611458 Nov 18 23:13 pixelserv.x86.debug.static*
-rwxrwx--- 1 root vboxsf   34668 Nov 18 23:13 pixelserv.x86.performance.dynamic*
-rwxrwx--- 1 root vboxsf 2085456 Nov 18 23:13 pixelserv.x86.performance.static*

The binaries run, but I still don't know how to use the ssl certs...

Code:
Nov 18 22:53:25  pixelserv[3384]: ./dist/pixelserv.x86.performance.dynamic version: V35.HZ12.Kf compiled: Nov 18 2015 22:52:52 options: -p 8080
Nov 18 22:53:25  pixelserv[3384]: Listening on :*:8080
Nov 18 22:53:25  pixelserv[3384]: setuid 65534: Operation not permitted
Nov 18 22:54:56  pixelserv[3399]: Sending HTTP 501 response for unknown HTTP method or non-SSL, non-HTTP request: #026#003#001
...
Nov 18 23:13:28  pixelserv[3384]: 1203 uts, 5 req, 217 avg, 324 rmx, 36 tav, 85 tmx, 0 err, 0 tmo, 0 cls, 0 nou, 0 pth, 0 nfe, 0 ufe, 1 gif, 4 bad, 0 txt, 0 jpg, 0 png, 0 swf, 0 ico, 0 slh, 0 slm, 0 sle, 0 slu, 0 sta, 0 stt, 0 204, 0 rdr, 0 pst, 0 hed
Nov 18 23:13:28  pixelserv[3384]: exit on SIGTERM

Making a test call from Firefox in the VM results in a browser message

Code:
Secure Connection Failed

An error occurred during a connection to localhost:8080. SSL received a record that exceeded the maximum permissible length. (Error code: ssl_error_rx_record_too_long)
 
Got your compiled version running a 14mb TinyCore image that I pxeboot. I can see it generating certs without issue now, however; all sites still give NET::ERR_CERT_AUTHORITY_INVALID in Chrome and a blank page in internet explorer. I have the cert imported as a Trusted Root CA authority, chrome even shows it as the certificate it flagged as bad. Or do I have to manually import EVERY cert that's generated? Any thoughts?
 
Last edited:

Similar threads

Latest threads

Sign Up For SNBForums Daily Digest

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