LavaTech WriteFreely


Read the latest posts from LavaTech WriteFreely.

from Ave's Blog

In case you haven't seen it yet, Discord is pushing age related systems pretty heavily lately.

There's two aspects of it, the age gate for NSFW channels, and ID verification for bot developers with bots in 100+ guilds. I'll be writing something on the latter on a future date.

The history

I believe the age gate is being rolled out to everyone these days, as me and lun-4 got it today, and linuxgemini and one of my other partners got it last week. That said, I have seen friends get it as part of A/B testing in the last couple months. As far as I know, the A/B testing on this started on or around 2020-04-03.

The importance

It is important to prevent minor's access to spaces containing sexual content, not just for their healthy development, but also to reduce risk of them getting groomed.

Some discord guilds take this matter more seriously than others. Some just rely on Discord's NSFW channel warnings (and ban anyone they know is under 18):

Some rely on people specifically requesting access to these roles, and some reportedly even ask you to do an ID verification with them, which while is a rather safe way to lock out people who are lying about their ages, it also puts the user's data at risk as they're transmitting it over an unencrypted platform to someone who may in turn not treat this data properly. It also creates privacy concerns.

The Snark

One issue I have with this is how it is presented. I was sending a command on our joins channel (which is marked as NSFW as we were flooded with bots with hateful usernames in the past) and closed my discord client there last night, and when I opened it this morning, it covered my entire screen, and asked me to input my birthday. Also, there was no way to close it, I couldn't just say “ask me later” and be locked out of channel until I entered my birthday. Clicking outside of the modal or pressing Esc also does not close it.

Discord does not do the discerning between “NSFW” and “sexual” content that well. As with the #joins channel I mentioned above, it is possible to have a channel that can benefit from a warning that it may not be safe to be viewed in a work environment (example, cw racism, transphobia, slurs), but one that isn't sexual.

In addition, what is “NSFW” depends greatly on your line of work and your culture. One could argue that looking at memes is NSFW by itself, or even spending company time on Discord. Over at elixire, we've decided to use “sexual” as a tag word to describe domains that allow sexual content (We currently don't allow sexual content on any domains, but plan to allow it on certain domains on v3 if the domain owner is okay with risking their domain ending up on parental block systems.) instead of “NSFW” to clarify this.

An age gate mostly benefits sexual channels, and IMO more channel types (announcements, chat, sexual, spoiler, disturbing, etc etc) with age gate only applied on channels that are sexual would be more appropriate than applying age gates to all sorts of NSFW content.

The Implementation

IMO, Discord did not implement this properly at all.

Here's all the issues that I've seen with it:

Fixed: Date format was unclear

Image source: This reddit post.

When this feature was first launched, it only allowed date entry in a textbox, in the format of mm/dd/yyyy. The problem with this approach is that many, many countries outside of US do not use this format, and use dd/mm/yyyy instead.

A friend of mine got locked out due to this as while she was 18+, her dd-mm swapped birthday was under 18. Yes, there was a notice on date format at the bottom, but it was a bad implementation. (The date shown is the current date, so date format is also not always fully apparent.)

This was replaced with a date picker in the end, with localized month names to prevent this from happening ever again. That was how it should've been in the first place.

This is a problem that could be prevented if discord was more diverse in the first place. I feel like Discord disallowing remote workers and not sponsoring visas is a factor in this.

If you pick the wrong birthday, you're stuck with it ...-ish

Discord does not allow you to change your birthday once you give it to them once. If you accidentally give them the wrong one (like my friend did) or if someone pulls a prank on you by grabbing your phone or something, you're locked out.

According to the official help article, the only way to change your birthday is by sending discord a picture of you holding a photo ID that contains your date of birth and a piece of paper with your full discord tag. Ouch.

There's no information on the data retention on this other than a weak statement saying that it'll only be used for age verification. There's also other issues with this as I will mention in the article I'll make about the ID verification systems employed by Discord.

TL;DR, though: – Not everyone has a photo ID. – Not everyone is comfortable with taking a picture of their face. – Not everyone is comfortable with transmitting their photo ID and a picture of their face to a private company.

And all of that is valid.

Note: When I discussed my concerns with Discord requiring you to send an ID to change your birthday with a friend, they told me that it's good for preventing the issues I mentioned in the “The Importance” section. While I respect this opinion, I kindly disagree, and wanted to state my reasoning here too: Users that want to lie about their age already can in the first prompt, so IMO disallowing changing your birthday mostly hurts those that aren't trying to bypass this procedure, but those that got locked out improperly.

Age gate encourages users to lie about their age

The whole system in general encourages users to lie about their age, and there's two overt examples of this that I stumbled upon while testing this.

The year picker dropdown automatically starts at 2002 when you click on it (It shows 2001, so you may ask “Ave, why did you say 2002?”, here's my explanation: If you pick a year like 1999, when you click on it again the year that's shown at the top of the dropdown will be 1998):

Year dropdown on age picker, top year is 2001, can be scrolled up a bit, and scrolled down a lot

The code for Android seems to do something similar too, defaulting to current date -18 years.

At first, both me and lun-4 assumed that this was the minimum age and this did bother us quite a bit as we felt like it forced you to lie about your age if you were under 18 (as you cannot close the age gate modal), but when I tested it further on an alt, I found out that this is definitely not the case (oddly enough it stops at 2017, I wonder why they picked 2017 specifically, that seems to be enforced on both desktop and android):

Year dropdown on age picker, top year is 2017, can't be scrolled up, can be scrolled down a lot

So, tl;dr: The year picker starts at the latest year in which an 18 year old person could be born.

Age gate tries to warn you if you say that you're underage

If you give a birthday that is less than 18 years old, discord will warn you:

This isn't displayed for people over 18.

While this is handy to prevent cases like the friend that accidentally got locked out, it does seem to also encourage you to lie about your age. Twitter also has a similar prompt before they lock you out of your account due to your birth year. Ideally, I think it'd be more appropriate if they showed this modal to everyone, not just people under 18.

Date calculation issues

Right, this is a big one. Discord does age calculations... weirdly. In some parts it does it properly and in some it does not, and this leads to some issues.

Flat out wrong calculations

On one account, I gave a birthday that's in 3 days (I picked close ones as I wanted to see if the lock would lift automatically on the birthday, it seems like that is the case, but I'm not 100% sure):

Age picker, date June 30, 2002

But in the end, I could still access NSFW channels:

Discord modal asking if I want to view this NSFW channel

Discord seems to calculate birthdays by doing (current date – your birthday), getting the day count, dividing it by 365 and seeing if it's over 18. This means that you get access to NSFW channels 4-5 days (depends on your birthday) early due to leap days.

Note: This is only valid for the desktop client, at least on Stable 62330 (912f791). Android seems to calculate it properly.

This is obviously a simple mistake to make, but it does show issues with QA testing on Discord, especially as this seems to be a deployed feature now.

Date calculation inconsistencies

(Test below was done on 2020-06-27, one day before the given birthday)

Animated image, of age gate, date given is 2020-06-28, discord asks user to confirm that they're 17, once confirm is clicked, user is shown into the channel (which is not visible), and not the you're too young error

The underage warning does calculate your age properly according to local time, but the code that locks you out of channels is not doing the same. Ngl, this is kind of amusing.

Checks are client-side

The birthday check is done on client-side and can easily be bypassed. I can't really fight too much over this, in the end there's much easier ways for someone to “bypass” it.

The Conclusion

That's all the issues I see with this specific system.

To me, it seems like it doesn't prevent the problems (as users can still easily lie), and goes too far by not allowing someone to update their birthday without sending a picture of them holding their photo ID and a piece of paper with their discord tag. Plus, it currently has bugs that allow minors who don't even lie to access NSFW channels.

I don't know what the proper way of dealing with this problem would be, but I can say with certainty that Discord's current approach isn't it.

This is a long and complicated topic. There's alternative methods, of course, but they're either weak (such as face verification), invasive and weak (such as credit card verification), or just invasive (such as ID verification). The UK had its own share of issues when it proposed such a system. While more invasive verification methods would increase the false positives and make bypassing the system harder, it'd also cause ethical concerns and potentially alienate adult users that do want to view and share sexual content. I know that I wouldn't send my ID to Discord over this.

And that concludes this blog post. Thank you for taking your time to read this.


from Ave's Blog

aka “How to use a ZTE MF110/MF627/MF636/MF190 on Linux in 2020”

Recommended reading before this post: A retrospective of 3G routers in Turkey

I was looking at random cheap networking stuff on the Turkish ebay clone the other day when I stumbled upon the good old 3G modems.

I always wanted one, and at some point one entered the house, but I never got a chance to use it, and I no longer am on good terms with the person who owns it now. I also ended up being given one by my grandparents several years ago, but I managed to break the sim slot before I could test it by storing a sim converter in it without the actual sim, which got stuck on the pins, and the attempts to pull it out led to the pins being destroyed. Ouch.

So, after all this time, I wanted to finally give it a shot, and they were being sold for as cheap as $3.5 + shipment, so I ordered the first one I saw, which was an “Avea Jet” model. It arrived this morning in a bootleg nutella box, and I had to pay like $2 to shipment. Yup. Can't make that shit up.

But yeah, the modem was inside that, wrapped in bubble wrap. I quickly opened it up, grabbed a SIM that has an actual data plan, found an appropriate SIM converter, stuffed it in:

So... I plugged it into my computer... and it didn't show up as a modem on neither modemmanager when I ran mmcli --list-modems, nor on dmesg:

Uh oh.

Back when my grandparents gave me their old one years ago, I didn't need to install drivers or do any special config for it to be detected, but I was running Ubuntu 16.04 back then.

This suddenly got me worried. What if the relevant kernel module was dropped since then? What if arch doesn't build it in? What if this device never got supported? What if the modem itself was broken? What if the modem is carrier locked (I was using a Turkcell SIM)?

I plugged it into the only Windows computer to try and figure out stuff, but that left me with more concerns, especially about the modem itself being broken, as the CD drive just decided to not load after some time, and as I couldn't see the modem in device manager.

So I started searching, and stumbled upon this arch wiki page, and it's pretty much the basis of this blog post.

I already had many of the software needed such as modemmanager, usbutils and mobile-broadband-provider-info, but turns out I also needed usb_modeswitch and also optionally nm-connection-editor for easy configuration of the settings (nmtui doesn't support it), and modem-manager-gui if you want a GUI for SMS.

The whole thing boiled down to:

# pacman -S mobile-broadband-provider-info modemmanager usbutils usb_modeswitch --needed
# pacman -S nm-connection-editor modem-manager-gui --needed  # these are optional
# systemctl enable --now ModemManager

But even after that, I was a little scared. usb_modeswitch --help talked about modes for huawei, cisco and many other manufacturers, but ZTE was missing from that list:

I sighed. I took a deep breath, and I re-plugged the modem and... what do you know, it showed up as a modem on dmesg and mmcli:

First off I opened modem-manager-gui, and sent a text to my girlfriend, who was able to confirm that she got it:

Being relieved that there's no apparent SIM lock or any other modem issues, I booted up nm-connection-editor, hit +, picked Mobile Broadband, and followed the wizard:

After saving, I finally booted up nmtui, disconnected from wifi and connected to the mobile broadband network:

And voila. I'm now writing this blog post while on a mobile network.

It's not fast by any means, but at least I can fall back to this in an emergency:

We're also planning having a similar setup on a colo with an IoT SIM so that we can still access the network if anything goes wrong.

That's all! Hope you enjoyed this blog post.


from Ave's Blog

aka “Ave tries to write a short blog post, dives into old ads, then adds a section about the history that's longer than the blog post topic itself, then splits the whole thing into two posts”

In late 2009 and most of early 2010s, starting from the 3G launch in Turkey (which was on 30 July 2009), Turkish carriers pushed 3G modems hard, especially Turkcell (which you may have heard of as “Lifecell” too, that's their new international brand name).

Turkcell's 3G modem was so popular that people tend to call 3G modems “VINN”s, which is what Turkcell branded their own installation of this as. While looking up resources for this, I saw many people calling the Vodafone 3G modems “vodafone VINNs”, though vodafone did themselves no favor by not having a decent name (they called it “vodem”). Avea's (nowadays called Turk Telekom Mobil) one was called “Avea Jet”, which was also rather memorable.

I'd also like to note that this isn't how this whole thing started, it existed before in some form or other, but they were even more obscure, and even more business oriented.

First they started with chunky modems, but after just a couple months moved to the USB modems (has low quality English hardsubs):

I personally don't know anyone who used the “chunky modems” as they were “chunky” and expensive (article says $189), but the USB stick ones popularized significantly.

The other operators jumped in on this, making their own variants:

You don't need to know Turkish to understand that these earlier ads are aimed at a white collar business crowd (though there are early examples of advertising towards a younger audience, such as this cursed ad).

Over the next couple years, prices went lower and lower, and adoption went up. Target demographic changed accordingly:

(Here's another Vodafone one that's rather generic, and another that's rather boring yet casual)

I don't have a good reason on why it was so popular, but one reason I can guess is the fact that ISPs in Turkey are a major pain in the back, and offer super slow speeds for large amounts of money. Currently, all major ISPs have a yearly or a biyearly contract requirement, with significant fees if you cancel the contract (one exception is TurkNet, they're working on getting their own infrastructure, but they're far from “major” still). I believe this was the same back then too.

These provided a nice way to have Internet wherever you go, not just at a fixed spot (can be a house you don't plan to live in for at least a year, can be your “vacation house”, can be a cafe, can be a park). Some of these did have contract requirements, but you at least had options that didn't require one, and even if you got into a contract, you could just take it with you when you moved. You didn't have to worry about infrastructure as long as the coverage was there.

Similarly, even though this was around the time we were starting to get decent smartphones, it was still not yet there. Things were slow, small and clunky, and to be fair, while social media and communications have definitely caught up, things still aren't the best when it comes to certain stuff like “productivity suites”.

These had really, really, REALLY bad software though, that did all sorts of hacks to work, were slow and prone to crashing (and Linux is a blessing when it comes to this, as you didn't have to deal with them):

(Image source)

(Image source)

(Also, apparently Turkcell wrote one of those horrible pieces of software for Windows 8. It states that that software only works with VINNs with Turkcell SIMs, btw.)

Around 2012, the WiFi variants of these popularized in Turkey. They allowed more users to connect (5-8), didn't involve using horrible software, and also worked on phones and tablets with wifi support. One example of these was the VINNWiFi:

(Turkcell previously offered this under the name “Multi VINN”)

I'm not too interested in these and won't talk much about them. Nowadays you can do the same task with any phone. Similarly, while I haven't messed with one so far, I imagine configuring it to work with any other carrier's SIM card wouldn't be as easy.

Over the years, popularity of this method of connecting to Internet gradually went down, with everyone I know either just getting a home connection (as you need Internet for many things these days) or using their phone to set up a hotspot. Or even just using their phone for everything (which is somewhat weird to me).

(Note: Turkey calls LTE “4.5G”. 4.5G is the same as 4G/LTE advertised anywhere else in the world.)

However, couple years back, Turkcell introduced “Superbox”es, promising fiber or even faster than fiber speeds. Considering that fiber coverage in Turkey isn't the best and that VDSL can get you around 75Mbps on a lucky day with a great connection (and more like 10Mbps if you're not so lucky), it seemed like a decent thing to introduce to the market, especially considering how Turkcell's 4.5G network is decent and I've personally seen it hit around 150Mbps or so (compare that to Vodafone where I've only seen upwards of 35Mbps or so).

However, these are pretty much where this retrospective started from: bulky GSM (well, in this case LTE) routers. Prices are sky high, there's quotas in place (as it's not a fixed internet connection), and reviews are horrible. 200GB quota at 4.5G speeds costs the same as unlimited 100Mbps fiber plan by Turkcell Superonline, and so does the unlimited 10Mbps plan. Yet people go for it anyways.

That's all for this retrospective. The point of this post was to help readers of my other post understand why they were once popular, but are not anymore, and subsequently why they're so easily available for so cheap.


from LavaTech Hall of Fame

Violet M. discovered a vulnerability on 2020-05-03 with our reverse proxy handling code and informed us through the mail address we specified on our security.txt.

We were using the X-Forwarded-For header for IP ratelimiting without realizing that IPs passed onto this aren't overridden by Cloudflare, but are appended. Relevant document can be found here.

This could potentially allow an attacker to bypass IP ratelimiting. We've deployed a fix shortly after she reported the issue to us:

We also deployed a workaround for our non-CF domains, which we will improve on v3. We did this by overriding the CF-Connecting-IP header with user's IP on nginx running on the routing server. We had been overriding X-Forwarded-For before this, so non-CF domains have been safe from this vulnerability the whole time.

Violet also found a potential vulnerability that an attacker with our IP addresses could abuse which was dependent on how our setup was configured behind the scenes, however this wasn't an issue that affected our specific setup as we have IP whitelists in place, and don't have as the default route on the routing server. Specifically, we limit to CF IPs on our routing server, and to routing server on the server that runs our elixire instance.

While the main instance at is safe from all these security issues now, we recommend anyone running elixire on their own server to upgrade to the latest master, and to deploy IP whitelists if they don't already have them in place (here's Cloudflare's IP list), and don't put elixire as your default route (as an attacker may put your IP to their Cloudflare account to bypass the whitelists). If you have a short list of domains, consider enabling Authenticated Origin Pulls.

We'd like to publicly thank Violet for helping us make elixire safer.

You may find/contact Violet at:


from LavaTech Blog

Hello everyone, XMPP Services had several (unannounced) downtimes today as I did some changes to

  • I've updated the server from ejabberd 20.03 to 20.04, released 4 days ago.
  • I've enabled STUN/TURN to enable Video/Audio calls. This is somewhat big. Here's the relevant issue, and a number of links explaining this. You may use this feature with Conversations. I haven't tested it yet, however if you do manage to try it out, please let me know if it works or not on email or XMPP [email protected]
  • I synced the configuration on the server to the one on the repository. The actual settings were the same, but locations of them weren't, and they missed notes etc from each other. I've synced these, mostly from the repo to the server. You can find the relevant commit here.
  • I've open sourced our MAM wiping systemd service/timer.
  • We've updated the SSL certificate. This is a downtime we have to face roughly every 80 days.

Thanks as always for using our services, Ave

(Tags to jump to other related posts: #a3pm)


from LavaTech Blog

Hey all,

As title says, we used to be a Manjaro ARM mirror for several months, but exactly 4 weeks ago, it became a part of Manjaro's regular mirrors. This was rather big and honestly amazing news for Manjaro ARM.

It did however mean that our mirror would be deprecated.

We thought of becoming a regular mirror, but couldn't find easy resources on how to become an official one quickly, and I (ave) was quite busy at the time, so it got kind of ignored.

Well, that changes today! We're now an official Manjaro mirror. Well, it was ready yesterday, but it got approved today, and we only switched it to the upstream today (that's the equivalent of a T2 Arch repo going to T1).

You shouldn't need to do much and it should get activated automatically based on ping, but if you want to add it manually, our mirror is at

Signed, LavaTech Team

(Tags to jump to other related posts: #manjaro #mirror)


from LavaTech Blog

Hello everyone,

I've just enabled experimental IPv6 support on XMPP services.

By that, I mean that I've:

  • Added AAAA records
  • Tested basic XMPP functionality (successful connection, fetching message history, sending messages) with an IPv6-only connection (which succeeded)
  • Updated nginx to also serve on IPv6 on port 80
  • Updated sslh to also serve on IPv6 on port 443

One thing that I haven't tested that has a chance of failing is HTTP file uploads/fetches with IPv6, though it very likely will work.

Please let us know if anything doesn't work! As always, you can reach us on [email protected] or [email protected] via XMPP or email, or use our Discord Guild.

As always, thanks for your interest in our services, Ave

(Tags to jump to other related posts: #a3pm #ipv6)


from LavaTech Blog

LavaTech Bitwarden is moving from Bitwarden to Bitwarden_rs

Hello everyone,

To make LavaTech Bitwarden better for both you and us, we're moving to bitwarden_rs, a third party bitwarden server.

We're sure that you're all well aware of certain issues LavaTech Bitwarden faced, especially regarding downtimes and email issues.

Bitwarden itself had certain issues:

  • It was written in .net core, used mssql etc, and was rather heavy for a small scale deployment like ours.
  • It required the use of docker-compose and was made out of ~10 containers. This didn't play nicely with our Docker network, leading to occasional downtimes and email issues.
  • It didn't allow accessing premium features or creating an organization without purchasing a license directly from Bitwarden, making self-hosting rather useless.
  • This was able to be bypassed with use of projects such as BitBetter ( We did use this, but that still required us to manually generate licenses for people.

bitwarden_rs has premium features enabled for everyone, you can create an organization without purchasing a license or asking us for a license file.

It's all self contained in one docker container, and plays rather nicely with our network. We've also fixed the email issues for both instances (that was mostly due to our messy network tho, which is now also sorted out).

And according to our early tests, it performs much better than Bitwarden itself, both in terms of actual performance and stability. If you had issues with it before, we recommend trying it out again.

Existing users

As the database in the backend isn't compatible with bitwarden_rs, we need existing users that want to preserve their data to follow these instructions:

  • Login to on a browser.
  • Go to Tools –> Export Vault, pick “.json”, enter your password, download your file.
  • Go to on a browser, register a new account, verify email, log in.
  • Go to Tools –> Import Data, pick “Bitwarden (json)”, select the file you downloaded, hit “Import Data”, and wait for it to finish. This process may take several minutes. There's a potential that it might time out and give an error, however it will still add everything in the background. Please do not try to add it again, it will just add duplicates.
  • Log out on any other device, extension etc you use Lavatech Bitwarden on, update domain to and login again.

Our old Bitwarden instance will be shutting down in a month (May 18, 2020), or when we confirm that all users have migrated, whichever is sooner.

Thanks for your interest, LavaTech Team

(Tags to jump to other related posts: #bitwarden)


from Ave's Blog

Superonline, aka SOL, aka Turkcell Superonline, aka AS34984 is one of the largest ISPs in Turkey.

One of the ads from the ISP, modified to say oof

I've been using their 100/5Mbps unlimited fiber service (their highest-end plan, other than the 1000Mbps one that has its own listing and costs 1000TRY/mo) for over a year now.

Let me tell you: I suffered a lot. Anything from random internet cuts to constant network-wide slowdowns whenever we watched anything on Netflix. I was constantly spammed with calls trying to sell me Turkcell TV+ (even when I told them that I don't watch TV countless times), and roughly 5 months before my contract expired, trying to sell me expensive and lengthy contract renewals*.

And even when it worked, it wasn't as fast as promised, at least over WiFi (5GHz): showing 45/20

Meet the routers

Huawei HG253

When I first got my Home Internet, I was given a Huawei HG253, a rather bad router: No 5GHz WiFi, horrible DHCP (can't even set static assignments), etc.

This is a rather hated router according to bad internet forums apparently (yes, I called donanimhaber bad, bite me).

Back then I set up a pihole instance at home just to deal with the DHCP issues (and ofc, also to block some ads).

All in all, this is how it looked like (before I did cable management haha I never did):

Huawei HG253

Thankfully though, the HG253 had a security vulnerability that ended up in my favor: It sent the PPPoE password to the client on the UI, and just marked the field as a password. You can literally just check the page source and get the PPPoE password. Back then I realized this and noted down the credentials (more on this later).

The HG253 had at least one public firmware (link of my HG253 files archive, including a user guide and firmware), and had SSH enabled.

I extracted this firmware and pretty much just explored it Back Then™, but found nothing too interesting. I think I found some hashed credentials but never bothered with hashcat-ing them. SSH was also out of question, it was ancient and even when I forced ciphers it liked to error out, I couldn't get very far with it.

I don't remember exactly what happened to this router, but IIRC it just died one day, and upon calling the support line, they replaced it with a...

Huawei HG255S

The HG255S, my current ISP Router, is a fairly decent router compared to HG253 and overall to other ISP routers I've used so far: It has 5 GHz WiFi (but it sucks, you saw the speedtests earlier), decent DHCP (after the HG253 it felt nice to have), 3G modem support, built-in SIP and DECT, USB port with Samba and FTP support, etc.

Huawei HG255S

However, as you may expect, most of these features are either locked down or behind a paywall. I'd honestly love to be able to modify the SIP settings so that I can have a DECT network at home that connects to my SIP network, but SOL only allows buying phone service from them. The SIP settings menu is removed from UI. More on all this later, this is what finally brought me to the point of replacing the router.

I still kept my Pihole install with this setup in order to not lose my DHCP and DNS data if my ISP ever swapped my routers again, and at that point, I was already doing a bunch of other odd stuff on that Pi anyways (like running openhab2).

“So just replace the router”

Well... Superonline doesn't allow you to replace their router if you're a fiber customer. The PPPoE credentials are not given to you even if you ask for them unless you're an enterprise customer (Relevant page for enterprise customers).

They hate the idea of you replacing the router. Whenever I call the support line with a technical problem they ask if my router is the one they gave or not.

There's literally no technical reason for this I can see, it's all red tape: The fiber cable doesn't even plug into the router, they give you a free GPON:

Huawei HG8010 GPON

The fiber cable goes into that and terminates as a female RJ45 port, which then gets plugged into the WAN port on their router. After that, it's just PPPoE.

I've previously looked into getting an inexpensive router that can run DD-WRT or OpenWRT to plug into the ISP router (and to limit the use of the ISP router to just serving the DD-WRT/OpenWRT router instead), but the things I found were either incredibly high end or simply unavailable. I ordered a router that can run OpenWRT couple months ago, and the order got canceled saying that they don't actually have any left. I gave up.

The straw that broke the camel's back

Couple weeks back, I was looking into messing with the HG255S again, mostly to figure out how I can get my own SIP stuff running on it so that I wouldn't have to worry about the horrible SIP implementation on my Cisco phone, and so that I could free an Ethernet port.

While doing my usual scouring to find any new information, I stumbled upon this specific post on a bad Turkish forum mentioning them running OpenWRT on the Xiaomi Mini router, and asking if moving to that would get them better performance. I quickly checked N11 (Turkish amazon, basically) and saw that there's some other Xiaomi Mi Routers, specifically the Mi Router 4 and 4A (Gigabit Edition). I checked their OpenWRT compatibility, and after seeing that they're supported, I ordered a 4A for merely 230TRY.

I considered getting something better that costs more, but due to COVID-19, I am trying to lower my expenses.

I also went ahead and dropped ~120TRY for a bunch of different programmers to have around, lol.

More on the Mi Router 4A

It's a Xiaomi Mi Router (to be called MiR) 3Gv2, in which 3Gv2 is just 3G, but worse. If you can get one of those, go ahead. Sadly though, they're not available in Turkey. It has 3 gigabit Ethernet ports, one for WAN. It has 2.4GHz and 5GHz WiFi.

It has support for OpenWRT snapshots, though it was broken as part of the move to Kernel 5.4 for over a week now. I talk more about this later.

It runs their own OpenWRT fork called MiWiFi:


MiWiFi is fairly decent and honestly, is pretty usable by default. However, as you might expect, it's not very extensible. I wanted to use Wireguard with this router, and MiWiFi simply didn't offer that (though it did have built-in PPTP and L2TP). There are also some privacy concerns I have with Xiaomi due to the amount of telemetry my Xiaomi Mi phone sends.

It has two ways of getting proper OpenWRT on it:

The physical way

You can go the physical way by opening up the device, dumping the SPI, changing the uboot parameters, then flashing it back.

This is safer as you have a point to recover to if you somehow manage to softbrick, but in the end, there are people who posted their own images on the Internet (which will change your MAC address btw, you'll need to edit your MAC back if you flash those images).

While noting down that I was unable to successfully dump the SPI as I couldn't get the programmer to see it, I was unable to find enough information on several parts of this process before I could even attempt it, so here are some tips:

Software (OpenWRTInvasion)

The other approach is to take the lazy approach and use the software exploit, OpenWRTInvasion. This is what I ended up doing in the end.

FWIW, to get stok (session token), open the panel ( and log in. It will be on the URL:


OpenWRT on MiR 4A time

Shortly after it arrived, I ended up installing a build from the OpenWRT forum, as the latest builds reportedly soft-bricked the device. I spent the day setting it up and learning how to use Luci (the Web UI) and OpenWRT.

Sadly though, I realized shortly after that I wouldn't be able to run Wireguard on it for some time as:

  • MiR 4A doesn't have stable releases, just snapshots.
  • The build I installed was an unofficial build (I later tried another build and it was one too).
  • Snapshots do not have packages for older versions (except kmods, but obviously only for official builds— I tried force installing one with a matching kernel version, but it obviously didn't work as it couldn't match the symbols).
  • The OpenWRT image builder uses the latest packages from the repo.
  • Official snapshots do not get archived, which means that I couldn't switch to an official version.

So a couple days later, I decided to make my own build. Being scared of bricking my router (even if I could recover from it, I didn't want the hassle), I ended up hours trying to find which commit was the last safe one and then realized that the version I'm running included a git hash in the version code. Oops. I ended up going with that one.

So I set up an OpenWRT build environment and built it for the first time, and while praying to tech gods to not lead to a brick, I flashed it.

And it worked... though it was missing Luci and a bunch of other packages as I compiled them as modules, not as mandatory. Apparently, module means that you just get the ipks, while mandatory means that you get the ipks AND it gets built into the image.

I SSH'd in and installed the Luci modules I compiled (it was painful, it's like 10 packages), then did another build with everything set as mandatory.

And sure enough, it worked! I quickly posted my build and talked about my success in the OpenWRT forum.

All basic functionality worked as expected AND it had the wireguard kmod, so I could call it a success, right? Well, no.

I just couldn't get wireguard to work, it did show as connected on the router, but when I checked on the peers, it didn't show up. I never used OpenWRT before so I had no idea if I was doing something wrong or not, so I simply noted that down on the forum post and moved on.

The next day though, someone who's an OpenWRT dev posted about a patch they proposed to fix the issue on master. I quickly applied the patch, improved the set of packages I include, compiled, flashed, confirmed that it worked and posted a build to the forum.

I had to reset the settings to get it to work due to these DTS changes, and after a reconfiguration, I was happy to see that wireguard actually worked... mostly.

While it did work for IPv4, IPv6 just kept not working. This happened when I tried 6in4 too, which is rather annoying as I've been wanting IPv6 at home or some time. I think IPv6 is just broken somehow. I'll dig into it more later.

Edit, a couple days later: IPv6 on router was okay, however there were two issues:

  • The server I was Wireguarding to ended up having constant issues due to upstream, leading to IPv6 downtime for some time (without me realizing it, oops).
  • I had no idea how to properly distribute an IPv6 block to LAN with Wireguard, and I still don't. Yell at me with instructions here.

Anyhow, I got it working. See the conclusion for more details.

This is mostly where the state of affairs is right now. A modified version of the proposed patch was merged into master, and I also posted a build including that, but there's not much noteworthy there, nothing in the build was changed.

Extracting SOL's PPPoE creds

And as promised, what you came for: PPPoE magic.

Well, first of all, I tried using the PPPoE credentials I extracted from the HG253, but they didn't work. It'd probably work if I still had the HG253, but it probably changed when my router was being changed to an HG255S. That's all there is to the “I'll get to this later”. Yep.

There are guides out there that talk about how you can extract the credentials, but these are all aimed at people who don't use Linux, basically writing guides that are helpful to people who aren't familiar with Linux, but wasting the time of those who are familiar. Some are better tho, but IMO could be improved.

Here's my take at it:

  • Log into your router, find the PPPoE username. It should look like this: [email protected]. Note it down.
  • Install rp-pppoe

On Debian-based distros: # apt install pppoe

On Arch-based distros: # pacman -S rp-pppoe

  • Edit /etc/ppp/pppoe-server-options

Change the contents to:

# PPP options for the PPPoE server
lcp-echo-interval 10
lcp-echo-failure 2
logfile /var/log/pppoe-server-log
  • Edit /etc/ppp/pap-secrets

Change the contents to (replace REPLACETHISWITHYOURUSERNAME with your username):

# Secrets for authentication using PAP
# client        server  secret                  IP addresses
  • Create the log file for rp-pppoe: # touch /var/log/pppoe-server-log; chmod 0774 /var/log/pppoe-server-log
  • Find your ethernet interface with ip a. Mine looks like enp3s0, it's what I'll use in the future commands, replace that with your own.
  • Shut down your router, plug in a cable to the WAN port, plug the other end to your computer.
  • Run # pppoe-server -F -I enp3s0 -O /etc/ppp/pppoe-server-options on a terminal, replace enp3s0 with your own interface.
  • Run # tail -f /var/log/pppoe-server-log on another terminal
  • Turn on your router, wait for a little until you see lines like this:
rcvd [PAP AuthReq id=0x7 user="[email protected]" password="no"]
sent [PAP AuthNak id=0x7 "Session started successfully"]
PAP peer authentication failed for [email protected]
sent [LCP TermReq id=0x2 "Authentication failed"]


  script /usr/bin/pppoe -n -I enp3s0 -e 7:no:no:no:no:no:no -S '', pid 4767
Script /usr/bin/pppoe -n -I enp3s0 -e 7:no:no:no:no:no:no -S '' finished (pid 4767), status = 0x1

Take the password from the first block, and the MAC address from the second one (ignore the 7: or whatever number from the start).

Now you have everything you need to replace your SOL router.

Finally: Replacing the ISP router with a MiR 4A

This is the simple part.

Plug the cable from GPON to your router.

Log onto Luci, edit WAN (and disable WAN6), change type to PPPoE, put in the username and password we got earlier into the PAP/CHAP username and password fields like this:

PPPoE settings

Then save and apply.

ssh into your router, edit /etc/config/network, find config interface 'wan'. Add a line to it (with proper indents) with something like option macaddr 'no:no:no:no:no:no'— replace no:no:no:no:no:no with the MAC address we found earlier.

Then finally run service network restart, and you'll be free from the curse that is Superonline's ISP routers.

In conclusion

My wifi speeds are MUCH better now :)

97/20 speedtest

And I can connect to our internal network without needing to VPN on the device itself :D

Me accessing a server on edgebleed

Soon I'll even be able to have IPv6 at home :P

I even have IPv6 at home, thanks to linuxgemini :3

IPv6 test showing IPv4 from SOL and IPv6 from Lasagna Ltd

Also: Capitalism is a failure, and free market ideologies are a joke. You don't get companies competing for cheaper prices, better service and less restrictions, you get companies all limiting their customers and all of them fucking them over in different ways. I am forced to use SOL because VodafoneNet and TT both have a contract minimum of 2 years, TT is unreliable AF, and TurkNet Fiber is unavailable in 99% of Turkey, including where I live, and everyone else are just resellers.

Bonus vent

*: I constantly turned down their offers as they were all worse than what I was already getting, or were slower than 100Mbps. I was also lied to, saying that fees would go up after the new year due to BTK, which was simply wrong, they still sell the same plan for the same price I started out my contract with. I ended up calling them 2 weeks before my contract expiry date, telling them exactly what I want (100Mbps, with contracts no longer than a year), they came up with a 15 month 100Mbps plan for 135TRY for the first 6 months, then 160TRY for the next 9. I kinda hesitated for the 15 months thing, but I said meh and agreed to it.


from LavaTech Blog

Istanbul, TR, Release: April 1, 2020. For Immediate Release.

Update, April 2, 2020: Date of post was bolded. and have announced today the planned merger of their operations to offer a unified file sharing solution to the market. will acquire the assets, community and hosting, and the merged business will operate under the ElixiLimited brand.

ElixiLimited Logo, founded in 2018, provides intelligent file sharing solutions that boost productivity, supercharge collaboration, and keep the organization connected. Its rich heritage in amusing domains and high uptime with long-standing partnerships with numerous other file sharing services provide a market leading proposition. is used by hundreds of users worldwide.

The expanded business will serve 1200+ users and 100.000+ files per day. is a main File Hosting Services provider in Istanbul. It has been solely focused on offering file hosting since the year 2018. Since its inception,’s business and service offering have evolved to meet the unique demands of the dynamic and maturing image host market.

To be the leading image hosting provider, has made stability the central element to everything that it does.

More information about the software products it offers can be found at the website of LavaTech:

A spokesperson for shared that they expect definitive agreements to be completed by 2 April 2020 and the operations and assets of to be transferred to shortly thereafter.

Contact info: Name: Ave Ozkal Organization: LavaTech Address: Chynoweth House Trevissome Park Apt 30074 Truro TR4 8UN United Kingdom Phone: +1-240-621-1337

(Tags to jump to other related posts: #aprilfools)


from Ave's Blog

I'm not the fastest typer, and I don't really use 10 fingers- I'm closer to 7 or 8, but I try to minimize the amount of keypresses that I make. This means that I use shortcuts a lot, and if there's a key for it, I use it. One example of this (that involves the delete key) is how I press delete instead of right arrow and backspace.

And ever since I got my Pinebook Pro, I felt the distinct lack of a delete key.

What's worse was the fact that in place of a delete key was a power key, one that, once tapped, depending on the DE either showed a power menu, or shut off the PBP:

Power button on PBP's keyboard, in place of delete key, at top right corner of keyboard, as an actual keyboard key (official image from Pine64 Store, modified with circle around power button)

One of the first things after I installed Manjaro ARM was disabling the power button's system shutdown effects in /etc/systemd/logind.conf, by setting HandlePowerKey=ignore (and restarting systemd-logind, which fyi kills X session)

Later on, to actually get it to work as a delete key I used something I did long ago, and just got the keycode from xev and set it with xmodmap to delete.

This wasn't perfect by any means, it had some delay, and some software like gimp just ignored it (which made image editing a lot more painful).

Then the project working on improving the keyboard and touchpad ended up releasing an update, one that allowed people to make their own keymappings.

I saw this while at work, put a note for myself:

The original note from February 9

I've been meaning to put aside some time to try and implement this behavior in the firmware itself, but I just couldn't find the time or the energy.

Until today.

The setup

I don't have much of a story to tell tbh. I cloned the repo, downloaded the requirements, compiled the tools.

I compiled and installed firmware/src/keymaps/default_iso.h (by following instructions on firmware/src/ just to see if it works or not, it did, so I continued on.

After setting up this new firmware, I did notice that some functionality worked differently though, such as:

  • numlock didn't turn ha3f 6f the 2eyb6ard 5nt6 a n40-ad (numlock didn't turn half of the keyboard into a numpad), but simply allowed the numpad area on the keyboard to be used with fn keys, which is a much better way of doing things.
  • Fn+F3 no longer pressed p. p.
  • Keyboard/Touchpad name changed from the actual part name to “Pine64 Pinebook Pro”, breaking my xinput set-prop settings. Simply renaming the device on the commands fixed this.
  • Sleep button combination (Fn+Esc) did not work (I don't use this combination, but the fact that it had the image on the keyboard and worked prior to the flashing bothered me).

The tinkering

I copied the file default_iso.h to ave_iso.h, trying to figure out how it's structured. I tried to find the power button, and I couldn't find it.

There was this vague keyboard shaped array with key mappings, and I did get how one half of them worked, but I couldn't understand how the other half did:

The keyboard shaped array

Well, I dug in the codebase for a couple hours, trying to figure out everything, and it finally made sense.

FR, FS and FK are just arrays that are mapped to fns_regular, fns_special and fns_keypad arrays in the same file respectively. This is all explained on the firmware/src/

The number (such as 6 on FR(6)) given as argument is the index from said array.

An example entry of REG_FN(KC_Z, KC_NUBS) means that default action is KC_Z, while action when Fn is held down is KC_NUBS.

KC means keycode, and they're mapped in firmware/src/include/keycodes.h. Do note that not all descriptions are correct in practice though, one example is that KC_SYSTEM_POWER says 0xA5, but 0xA5 is actually used for brightness up (I explain why this is the case later).

The R() function used on rest of the keyboard are “Regular” keys, ones that have no actions with Fn. They're directly passed on to their KC_ versions.

If you hate yourself, you can also supply regular integers in place of any of the aforementioned functions and anywhere where you see a KC_, and this did help when I was trying to understand how things work.

FK is only able to be used with Fn keys when numlock is open. I'm not exactly sure what the difference of FR and FS are outside of semantics. (Looking at my own PR, I regret using FR instead of FS as I'm not fitting the semantics properly. Functionality seems the same though.)

I ended up implementing the sleep button combination, and I learned a lot about keyboards while trying to figure out how I could even emulate the power button. I have some links that I used during my adventure at the bottom of this article. I sent a PR with that patch and it got merged.

The realization

After asking around on the Pine64 #pinebook channel, I was told by a helpful person that the power button is wired to the SoC directly, and that SoC sends the power key input itself (or rather, that this input was handled by the device tree in the linux kernel and turned into an actual emulated keypress).

Most importantly however, they said that it could be remapped with udev. Now, I had only used udev rules to date,and it got me rather confused as I had no idea how one would remap anything with that. That got me to research how to do that, and I learned about a tool that I never used before: evtest.

And sure enough, I found it:

gpio-key-power on evtest's device list

Upon picking gpio-key-power and hitting the key, I immediately saw the keypress (this image was taken after the change, so it says KEY_DELETE, before the change it used to say KEY_POWER):

Power key press event on evtest

Upon more research, I learned how to write hwdb entries in udev, not rules. Similarly, I found an already existing hwdb file in /etc/udev/hwdb.d/10-usb-kbd.hwdb, which explained why the KC_SYSTEM_POWER key was mapped to brightness up: Because the hwdb was set up this way. For reference, here's what it looks like:


This also explained to me why KC_POWER caused a sleep action and not a power key action when done through the builtin keyboard (but not through the dedicated power button).

The ending

I quickly wrote a hwdb file myself on /etc/udev/hwdb.d/20-power-button.hwdb:


And upon recreating the hwdb file with # systemd-hwdb update and triggering the hwdb with # udevadm trigger /dev/input/event2, the power button started working as a proper delete key.

evtest saw it as KEY_DELETE, the delay when tapping it rapidly vanished, and stuff like gimp started to acknowledge it. Now I just need to avoid holding it down.

Handy resources