Friday, April 29, 2022

Using WireGuard to forward ports from behind a CG-NAT

I am using WireGuard, which I have installed on my VPS, to be able to forward ("open") some ports that I need to run SoulSeek, even when my ISP has put me behind a CG-NAT. I imagine that these instructions (after some adjustments) can be used for other VPN solutions and other applications that need you to forward some ports to run properly such as BitTorrent clients and such.

This tutorial assumes that you already have WireGuard installed and running. If not, you can use any other tutorial or script to install WireGuard.

The easy way would be to install the WireGuard client on Windows and then load your configuration file, but that would mean that all your traffic gets routed through your VPN, which is something that I want to avoid.

WireGuard

First we need to install the WireGuard client and make some changes to the client configuration file so, by default, no traffic goes through the VPN. Every connection has what we call a "metric" which is something like the priority of that connection. We have to tell WireGuard to change the metric of the VPN interface to a high value so this interface is never used by default.

This post explains it well: Split Tunneling in WireGuard on Windows (archive)

iptables

We need to use iptables to forward all incoming connections to the WAN interface of our VPS to the VPN interface. We use the following command once for every port that we need to forward:

iptables -t nat -A PREROUTING -p tcp -d <WAN IP> --dport 51211  -j DNAT --to <VPN client IP>

In this case, WAN IP is the public IP address of our VPS, while the VPN client IP is the IP address that our client gets when it logs into WireGuard. You can see it in the Interface -> Address option of your WireGuard .conf file.

Since iptables rules are reset on reboot we need to figure a way of making the rules persistent. I use iptables-persistent; configuring it is beyond the scope of this article.

SoulSeek (or any other application)

We have to tell the application that we want it to bind to the VPN client address instead of the default address. Most network-oriented applications allow you to specify what IP address you want to bind to, but some don't, and SoulSeek is one of those that don't. But there's a solution: ForceBindIP.

We need to find what the GUID of our VPN tunnel is. Using the Registry Editor, we have to go to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces and find that interface. In the case of WireGuard you will recognise it because of the NameServer values. Copy the GUID and turn it into uppercase to bypass a bug in ForceBindIP. Then you can launch SoulSeek by creating a shortcut like this:

Target: C:\Software\ForceBindIP\ForceBindIP64.exe {DD63324A-14EB-D556-77E6-C4120A4D65A4} "C:\Program Files (x86)\SoulseekQt\SoulseekQt.exe"

Start in: "C:\Program Files (x86)\SoulseekQt"

You have to use either ForceBindIP.exe or ForceBindIP64.exe depending on whether the application is 32-bit or 64-bit.

Once the application launches and you have configured the ports that you forwarded before (and restarted the application if necessary), you can try one of those online services that check for open ports. Use your VPS IP address and the port(s) you forwarded and they should display as open.

Take into account that the fact that the port shows as open doesn't mean that the application has managed to bind to the IP address of our VPN client, since most applications accept connections on every interface, including the VPN interface. How to check which IP address the application is using will depend on the application. In the case of SoulSeek, we can try Nicotine+ from another computer, which allows us to see the IP address of other users. You can also check if you can browse your own shares and download stuff.

Thursday, April 7, 2022

Bookmarks

 My list of bookmarks, rescued from my old blog.

  • Reset NTFS ACLs (another source)
  • rundll32 Shell32,Control_RunDLL input.dll,,{C07337D3-DB2C-4D0B-9A93-B722A6C106E2} — disable all keyboard layout switching shortcuts.
  • powercfg.exe /SETACVALUEINDEX SCHEME_CURRENT SUB_VIDEO VIDEOCONLOCK 60
    powercfg.exe /SETACTIVE SCHEME_CURRENT — change the amount of time it takes for the screen to power off after you lock your computer.
  • mountvol E: /s
  • bcdboot D:\Windows -s E: — fix a broken BCD (D is the system disk, E is the ESP).
  • rsync -arvzP --bwlimit=1000 example.com:~/folder/ . — synchronise two folders.
  • In C:\Program Files\Microsoft Office\Office16:
    • cscript OSPP.VBS /dstatus
      cscript OSPP.VBS /unpkey:XXXXX
      (remove the one that’s wrong)
      cscript OSPP.VBS /inpkey:XXXXX-XXXXX-... (install a new one)
      cscript OSPP.VBS /sethst:kms.example.com
      cscript OSPP.VBS /act
      — activate a copy of Office 2019. Only works with volume licences (VL).
  • -noforcemaccel -noforcemparms -noforcemspd — launch parameters to be used with GoldSrc games so they don’t enable mouse acceleration/enhanced pointer position.
  • Game overlays don’t work while RivaTuner Statistics Server is running

Sunday, March 20, 2022

Warmane: scripts sent by Sentinel

During login and while you play, Sentinel sends some Lua code to your client using the addon message channel. It's not clear to me how this code is executed once it arrives to the client or why is it being sent using addon messages. Some of these scripts add UI features while others try to catch cheaters. 

I am publishing this as a technical curiosity more than anything else. Excuse the format, I know how much blogspot sucks for posting snippets.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if(OriginalClearTarget==nil)then
    OriginalClearTarget=ClearTarget
    ClearTarget=function()
        if(issecure())then
            NewClearTarget()
        else
            RegisteredFrames={GetFramesRegisteredForEvent("MACRO_ACTION_FORBIDDEN")}
            RegisteredFramesCount=getn(RegisteredFrames)
            for i=1,RegisteredFramesCount do
                RegisteredFrames[i]:GetScript("OnEvent")(RegisteredFrames[i],"MACRO_ACTION_FORBIDDEN","ClearTarget()")
            end
        end
    end
end

Relays the event MACRO_ACTION_FORBIDDEN to all subscribed frames whenever the protected function ClearTarget() is used by tainted code.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

local LogoutFrame=CreateFrame("Frame")
LogoutFrame:RegisterEvent("PLAYER_LOGOUT")
LogoutFrame:SetScript("OnEvent",function()
    SendAddonMessage('(redacted)','(redacted)','WHISPER','(redacted)')
end)

Sends back a message whenever the player logs out or reloads the interface. 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if not (UnitPopupButtons["PVP_REPORT_AFK"]) then
    return
end
local soloqueueFrame=CreateFrame("Frame")
soloqueueFrame:RegisterEvent("UPDATE_BATTLEFIELD_STATUS")
soloqueueFrame:SetScript("OnEvent",function()
    local a,b,c,d,e=GetBattlefieldStatus(1)
    if (e==0xFF) then
        SOLOQUEUE_AVOID_TEAMMATE="Avoid as Teammate"
        UnitPopupButtons["PVP_REPORT_AFK"].text=SOLOQUEUE_AVOID_TEAMMATE
    else
        UnitPopupButtons["PVP_REPORT_AFK"].text=PVP_REPORT_AFK
    end
end)
soloqueueFrame:GetScript('OnEvent')()

This is the code that adds the "Avoid as Teammate" option in soloq games.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

local XPRate,XPRates,dropDown=7,{0.5,1,3,5,7},CreateFrame("Frame","XPRM",MainMenuExpBar,"UIDropDownMenuTemplate")
UIDropDownMenu_Initialize(dropDown,XPRMDD,"MENU")
MainMenuExpBar:SetScript("OnMouseDown",function(self,button)
    if button=="RightButton" then
        ToggleDropDownMenu(1,nil,dropDown,"cursor",3,-3)
    end
end)
UIDropDownMenu_Initialize(dropDown,function(self,level,menuList)
    local info=UIDropDownMenu_CreateInfo()
    local title=info
    title.text=EXPERIENCE_COLON
    title.isTitle=1
    UIDropDownMenu_AddButton(title,level)
    info=UIDropDownMenu_CreateInfo()
    info.func=self.SetValue
    for i=1,#XPRates do
        local currate=XPRates[i]
        info.text,info.arg1,info.checked="x"..currate,currate,currate == XPRate
        UIDropDownMenu_AddButton(info,level)
    end
end)
function dropDown:SetValue(xp)
    XPRate=xp
    SendAddonMessage('(redacted)',xp,'WHISPER','(redacted)')
    CloseDropDownMenus()
end

This is the dropdown that allows you to choose an experience multiplier by right-clicking the experience bar.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

MERCENARYMODE_ENABLED=false

function ToggleMercenaryMode(a,t)
    MERCENARYMODE_ENABLED=t
    SendAddonMessage('(redacted)',t and 1 or 0,'WHISPER','(redacted)')
    CloseDropDownMenus()
end

local function b(a,c,a)
    if c==2 then
    local d=UIDropDownMenu_CreateInfo()
    d.text="On"
    d.checked=MERCENARYMODE_ENABLED
    d.func=ToggleMercenaryMode
    d.arg1=true
    UIDropDownMenu_AddButton(d,c)
    local d=UIDropDownMenu_CreateInfo()
    d.text="Off"
    d.checked=not MERCENARYMODE_ENABLED
    d.func=ToggleMercenaryMode
    d.arg1=false
    UIDropDownMenu_AddButton(d,c)
    return
end

MiniMapBattlefieldDropDown_Initialize()
    local e=0
    for f=1,MAX_BATTLEFIELD_QUEUES do
        s,a,a,a,a,t,r=GetBattlefieldStatus(f)
        if s=="queued" and t==0 and r~=1 then
            e=1
        end
    end
    
    if e==1 then
        local d=UIDropDownMenu_CreateInfo()
        d.isTitle=1
        d.notCheckable=1
        UIDropDownMenu_AddButton(d)
        local d=UIDropDownMenu_CreateInfo()
        d.isTitle=1
        d.notCheckable=1
        d.tooltipWhileDisabled=1
        d.tooltipOnButton=1
        d.tooltipTitle="Mercenary mode allows you to enter Battlegrounds as a member of the opposite faction for improved queue times."
        d.text="Queue Options"
        UIDropDownMenu_AddButton(d)
        local d=UIDropDownMenu_CreateInfo()
        d.text="Mercenary Mode"
        d.notCheckable=1
        d.hasArrow=1
        UIDropDownMenu_AddButton(d)
    end
end

local function g()
    UIDropDownMenu_Initialize(MiniMapBattlefieldDropDown,b,"MENU")
end

g()

local h=CreateFrame("Frame")
h:RegisterEvent("PLAYER_ENTERING_WORLD")
h:SetScript("OnEvent",OnEvent)

This is the code that allows you to toggle mercenary mode in the battleground button dropdown.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if(issecurevariable("ClearTarget")) then
    SendAddonMessage('(redacted)','(redacted 1)','WHISPER','(redacted)')
else
    SendAddonMessage('(redacted)','(redacted 2)','WHISPER','(redacted)')
end

This one is sent periodically. It will send different addon messages depending on whether you interfered with the modifications done by the first script or not.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if(something)then
    local function IsLowercase(input)
        -- returns 97 if all chars in input are lowercase else 65
        return input:lower()==input and ('a'):byte() or ('A'):byte()
        end

    local function Unscramble(str,inputKey)
        return (str:gsub('%a',function(input)
            local caseKey=IsLowercase(input)
            return string.char(((input:byte()-caseKey+inputKey)%(28+10-12))+caseKey)
        end))
    end

    local CVarName="(redacted)"
    local MyInputKey=7
    local GetCVar_fun="(redacted)"
    local strlen_fun="(redacted)"
    local SendAddonMessage_fun="(redacted)"
    local Channel=Unscramble("(redacted)",-(MyInputKey*3))
    CVarName=Unscramble(CVarName,(MyInputKey+3))
    SendAddonMessage('(redacted)',_G[Unscramble(strlen_fun,12)](_G[Unscramble(GetCVar_fun,(MyInputKey))](CVarName)),'WHISPER','(redacted)')
end

This checks if there is a cvar called "SCRIPT_HANDLER_LOAD" and if so it sends its length back to the server as an addon message.  

There's a very similar one that checks for the existence of a function called "unlock". If detected an addon message is sent also.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if(FirstFrame)then
    FirstFrame:UnregisterAllEvents()
    FirstFrame:SetScript("OnUpdate",nil)
    FirstFrame.(redacted)=0
    FirstFrame.(redacted)=0
    FirstFrame=nil
end
if(OriginalClearTarget)then
    ClearTarget=OriginalClearTarget
    OriginalClearTarget=nil
end

Not sure about this one at all. Seems to undo some of the previous things, although I see no reference to FirstFrame in any of the other scripts (perhaps an older script that is no longer in use?).

Sunday, November 7, 2021

On IRCCloud

I've known irccloud (or ircclown as some call it) for some time; we've had an on-again, off-again relationship for years. My biggest gripe with it is that, if you don't pay, it disconnects you after a few hours of inactivity (inactivity being described as not having an irccloud tab open: you don't have to talk if you don't want to). Also it doesn't let you connect to more than two servers, and you can't use server passwords, but who needs anything else than passwordless efnet, right?

Keeping the connection alive

I tried writing a script myself. The idea was that every x minutes the script would log in, idle for a few seconds, then disconnect. That should be enough. Well, I tried, and it didn't work. I kept getting disconnected. Obviously I had to work on it a little bit more, but then I found this: https://github.com/osm/icka/

It's neat: it works. You just put it in your crontab and forget about it.

*/30 * * * * ./icka/icka -email 'thisis@myemail.com' -password 'whyyoulittle'

I learnt more about the irccloud protocol than I would've wanted to - it works over websocket and it's not obfuscated or anything. It's quite straightforward. Looking at it made me wonder how easy or hard it would be to write an irc bot that connects through irccloud. Something to try someday.

Styling

Being a web application, we can apply any styles that we want. In my case, I've made a few changes.

As you know, you can use some browser extensions like Stylus to add CSS code to any website, but myself I like to do it using uBlock Origin. Why? Because I already have a uBlock Origin list for my own purposes, which I share with all my computers, so my CSS changes (and blocked elements) are synchronised automatically. Neat.

These are all filters you can add to the "My filters" tab in the uBlock Origin configuration page.

  • Bring back the < and > symbols to nick names:
    irccloud.com##.messageRow .authorWrap > .g:style(display: inline !important; position: unset !important; left: 0 !important; top: 0 !important)
  • Hide automatically generated avatars (the ones with a letter), leaving only the user-set ones:
    irccloud.com##.messageRow .avatar.letterAvatar
  • Change the monospace font from Hack (the default) to anything else:
    irccloud.com##body.font-mono #timeContainer, body.font-mono .buffercontainer, body.font-mono .buffercontainer button.link, body.font-mono .fontChooser__sample, body.font-mono .inputcell textarea, body.font-mono .messageLayout__preview, body.font-mono div.shim:style(font-family: "Consolas" !important)
  • Eliminate the white lines in between irc art without having to use compact mode, which packs all chat lines too tight. (This makes colour blocks a bit too tall - some may not like it and there probably are better options):
    irccloud.com##.messageRow .irccolor:style(padding-bottom: 8px)
    irccloud.com##.messageRow:style(line-height: 17px !important)

Scripting

Theoretically you should be able to automate some things using userscripts. I haven't tried, but I'm leaving the idea here in case someone wants to pick it up. This option is reasonable for itsy-bitsy automations. If you want to write a full-fledged bot, I think you'd be better off using the irccloud protocol, as I suggested above.

Password-protected servers

If you need to connect to a password-protected server, you have to pay. But you should be able to write a script that proxifies all incoming connections and sends the PASS command at the appropriate time. Once again, this is a theory as I haven't actually tried, but I don't see why it shouldn't work.

Other options

You also have the option of using The Lounge. It's something I've considered, but they have no mobile apps. I asked on their irc channel and they told me that I don't need an app because the site itself is a PWA. I couldn't help but scoff at the situation.

irccloud also allows you to upload small files and a link is posted automatically to the channel you're in. It's the kind of thing you didn't know you needed until you had it.

And hey, if irccloud doesn't win you over, you can always go back to irssi on tmux.

Friday, October 8, 2021

El software que uso

Voy a poner una lista del software que uso en Windows, tanto como para recordar qué tengo que instalar cuando formateo como para dar la oportunidad a otros de conocer nuevo software.

  • MPC-BE: reproductor de vídeo.
  • HxD: editor hexadecimal.
  • CopyTrans 3uTools: para poder subir y bajar música del iPhone. La única app que he encontrado que se actualiza y que no es de pago.
  • WinSCP: cliente de SCP/FTP/etc que además permite editar archivos directamente sin bajarlos y subirlos.
  • WSLtty: terminal para wsl que le da mil vueltas a la terminal estándar de Windows (cmd).
  • 7-Zip ZS: fork de 7-Zip con soporte para Zstandard y otros algoritmos más de compresión.
  • AltServer: para instalar apps piratas en el iPhone.
  • IrfanView: visor de fotos.
  • ShareX: captura fotos y vídeos o gifs del escritorio y los sube automáticamente a distintos hosts (o no).
  • Afterburner y Rivatuner: permiten hacer overclocking a la GPU y muestran un overlay con estadísticas (FPS, temperatura, etc) en los juegos.
  • Notepad++: editor de texto.
  • AutoHotkey: creador de atajos. También se puede usar para deshabilitar los que vienen con Windows por defecto. Aquí hay un ejemplo de un script que uso yo, pero tengo otros para, por ejemplo, automatizar tareas en el WoW.
  • SumatraPDF: visor de PDF.
  • KKCap: para poder pasar por un proxy socks/etc las aplicaciones que uno quiera, aunque no soporten proxies. Por ejemplo, lo he usado para jugar al WoW mediante un túnel SSH.
  • WinCDEmu: para montar imágenes ISO y otros formatos. Mucho mejor que la funcionalidad que lleva Windows incorporada.

Tuesday, April 6, 2021

Mis hábitos de navegación

La aplicación que más usamos cada día es el navegador, así es que tiene sentido emplear tiempo en elegir uno, en configurarlo y en instalar un conjunto de extensiones para facilitar su uso.

Elección de un navegador

En 2021 hay tres autovías con varias carreteras adyacentes:

Blink

Chrome es el "gold standard"; todos los conocemos, y el resto de navegadores que usan Blink se comparan a él. Está casado con Google, pero dentro de lo que cabe es configurable para que no te dé la brasa mucho con iniciar sesión. Quitando eso, es espartano y se quita de en medio. No suele haber sorpresas desagradables a la hora de actualizarlo (con algunas excepciones). Lo de la falta de sorpresas desagradables puede sonar raro pero es una excepción en el mundo de los navegadores, como veremos más adelante.

La versión de Blink de Microsoft Edge ("Edgium") comenzó su andadura como un fork de Chrome sin rollos de Google y una integración con Windows un poco más currada. Pero Microsoft es Microsoft y con el paso del tiempo no han podido evitar añadir más y más cosas hasta llegar al punto en que uno se plantea si realmente merece la pena usar Edgium en lugar de Chrome.

Chrome implementó recientemente una funcionalidad para agrupar pestañas que, si la habéis usado, habréis visto que es intuitiva y bonita; Edge en su lugar tiene otra funcionalidad que llaman "Collections" y que es mucho más compleja y lenta. En versiones recientes también reemplazaron la página del historial con un desplegable que es lento y que, al contrario que la página de historial, no pone el foco en el buscador por defecto. Cuando quiero buscar algo en el historial, pulso Ctrl+H y escribo inmediatamente, cosa que funciona hasta en Firefox, pero Microsoft ha decidido que tengo que coger el ratón para pulsar el icono de la lupa si quiero buscar. Son estos pequeños cambios sin sentido los que acaban cansándome.


Por no hablar del obvio interés que tienen por que uses Bing. Mi interés es de cero, como es natural. Por ejemplo, añadieron una funcionalidad para buscar algo en una barra lateral, pero está "hardcodeada" para usar Bing, y por lo tanto no la puedo usar nunca:


Durante mucho tiempo usé Brave, pero tenían la misma costumbre de Edge de incordiarme cada dos por tres. Brave tenía alguna cosilla inútil activada por defecto, como lo de dar propinas a las web con criptomonedas, pero se podía desactivar. Para mí la gota que colmó el vaso fue cuando decidieron añadir un formulario para comprar criptomonedas con Binance a la página de nueva pestaña. 

Se podía desactivar, claro, pero no quiero estar cada x semanas desactivando cosas nuevas. Al final acabas con un mal gusto en la boca porque sientes que el navegador está en tu contra. Como dije más arriba el navegador es la aplicación que más uso y no quiero pasarme el día usando software que es hostil.

También di varias oportunidades a Vivaldi. El equipo de Vivaldi decidió que era apropiado reescribir toda la interfaz del navegador desde cero usando JavaScript. El resultado es una interfaz exasperantemente lenta y a la que le faltan funcionalidades básicas. Voy a poner un ejemplo: para buscar algo en Google, o para abrir un enlace en una nueva pestaña, arrastro texto o un enlace a la barra de pestañas, así:


Tal cosa funciona en todos los navegadores menos Vivaldi. Cualquier persona con dos dedos de frente y un poco de experiencia sabe que reescribir una interfaz es muy mala idea porque tienes que implementar los innumerables comportamientos que tiene la interfaz anterior. Igual que este ejemplo hay muchos más, pero de memoria no puedo mencionar ninguno porque hace ya muchos meses que no uso Vivaldi.

Con respecto a los navegadores Blink en general, hubo mucho revuelo cuando en Google decidieron que eliminarían la API que las extensiones como uBlock Origin usan para inspeccionar y bloquear peticiones HTTP y la sustituirían por una más básica, similar a la que tiene Safari. En su momento recuerdo que algunos forks de Chrome se posicionaron en contra de este cambio y anunciaron que no lo implementarían. Cuando estos cambios se hicieron públicos pensé que tendría que investigar más al respecto, pero llevo algún tiempo usando Chrome y no he encontrado ninguna página que muestre anuncios que no se puedan bloquear, así es que es posible que el revuelo haya sido un poco exagerado. 

Gecko/Firefox

Por desgracia no hay mucho que decir con respecto a Firefox. Al igual que los forks de Chrome, a cada nueva versión meten nuevas funcionalidades hostiles y, lo que es peor, publicidad. La parte positiva es que hay una versión LTS llamada Firefox ESR que se actualiza cada mucho tiempo y que se puede usar para escapar los cambios continuos que incluyen en la versión normal.

Para mí, Firefox acaba siendo un navegador similar a Brave: incluye un bloqueador de publicidad y rastreo que es completamente superfluo teniendo en cuenta que uBlock Origin es la primera extensión que instalo en cualquier navegador, y con las nuevas versiones meten publicidad y rediseñan partes de la interfaz sin necesidad. A esto hay que sumar la muerte de las extensiones XUL. Tras todos estos años, Firefox no es más que una versión más lenta de cualquier fork baratucho de Chrome.

WebKit/Safari

Safari es el navegador que usaba en Mac. Creo recordar que no tenía soporte de WebExtensions y la única extensión que usaba era un fork sin soporte de uBlock Origin. Aun así es tan, tan rápido que merece la pena probarlo. Habrá a quien no le guste Safari por la falta de funcionalidades, pero para algunos puede ser un punto a favor.

Algo más

Microsoft tiró la toalla con el viejo Edge de EdgeHTML y Chakra. Probé Edge en su momento y me pareció un navegador rápido y sólido, pero para mí la interfaz Metro (o como la queramos llamar) lo mató. Las interfaces Metro de Windows son feas, poco intuitivas, y sobre todo lentas. El retraso que tenía Edge a la hora de abrir una nueva pestaña era completamente inaceptable. Microsoft podría haber ganado mucho mercado con Edge si este hubiera usado una interfaz Win32 y hubiera tenido soporte para WebExtensions.

Para garantizar una competencia sana en la web, debería haber más motores de renderizado y de JavaScript. A Google les interesa mantener el control de la web mediante Chrome, cosa que consiguen hinchando los estándares web hasta el punto que nadie más (ni siquiera Microsoft) puede gastar dinero para mantener un motor web. Mozilla debió haber usado su cuota de mercado para plantar cara a Google en este sentido, pero con el tiempo ha quedado claro que es una organización inútil y disfuncional. Ya es tarde y está claro que Firefox morirá. Apple sí ha plantado cara a Google negándose a, por ejemplo, implementar la API de notificaciones, pero cuando Firefox no exista no sé qué hará Google con tal poder. Seguramente el tema acabe en los tribunales.

Configuración

La configuración de un navegador no tiene mucha miga. En mi caso:

  • Desactivo todas las funcionalidades de inicio de sesión, etc. También desactivo los servicios de ayuda a la navegación, telemetría, etc. siempre que sea posible.
  • Desactivo las cookies de terceros. No sirven para nada bueno.
  • Deniego los permisos para usar APIs hostiles como notificaciones, geolocalización, micrófono y cámara, etc.
  • Desactivo las funcionalidades de bloqueo de publicidad, rastreamiento, etc. porque prefiero gestionarlas desde uBlock Origin.

Extensiones

Estas son algunas de las extensiones que uso en todos los navegadores.

Cookie AutoDelete

Esta extensión elimina cookies, localstorage, service workers, etc. de las webs en cuanto cierras la pestaña. En teoría suena muy bien, pero en mi experiencia por restricciones de la API de extensiones no consigue eliminar todas las trazas de todas las webs. Aun así prefiero dejarla puesta. Por ejemplo, gracias a esta extensión no recibo sugerencias en YouTube basadas en los vídeos que he visto anteriormente, cosa que no me gusta.

Enhancer for YouTube

Unas cuantas funcionalidades automáticas para YouTube: desactiva la reproducción automática del siguiente vídeo, abre los vídeos a ancho completo por defecto, permite aumentar el volumen de los vídeos a más del 100%...

Imagus

Esta extensión muestra todas las imágenes que encuentras en la web en grande. Es capaz de convertir las URLs de miniaturas en URLs a tamaño completo, muestra las imágenes que hay en enlaces con sólo pasar el cursor por encima, etc. También tiene atajos para girar y espejar imágenes y abrirlas en una pestaña nueva.

Hace muchos años se usaba otra extensión similar llamada HoverZoom, pero le metieron malware o algo así y murió violentamente.

LocalCDN

Contiene copias de muchísimos de los scripts que hay en CDNs como la de Google para que carguen más rápido y sin hacer peticiones HTTP a servidores de terceros.

Redirector

Permite crear reglas de redirecciones de URLs. Tengo creada una lista de reglas para que, por ejemplo, al pinchar en un enlace de la versión móvil de Wikipedia se me redirija a la versión completa. Aquí está la lista de redirecciones que uso yo:

https://gist.githubusercontent.com/wodim/091c90244c34f075766f3a8c8363faca/raw/Redirector.json

Reverse Image Search

Muy útil para encontrar la versión original de una imagen, o la misma imagen a mayor resolución. Viene con varios servicios de búsqueda de imágenes configurables. En mi caso uso Google, TinEye, Bing y Yandex.

Tabby Cat/Empty New Tab Page

Todos los navegadores han acabado incorporando una lista de las webs que más visitas en la página de nueva pestaña. Me parece una trampa mortal porque acabas pinchando casi sin querer y perdiendo mucho el tiempo. Puedes mejorar mucho la página de nueva pestaña poniendo un gato de colores.

uBlock Origin

No hay mucho que decir al respecto de esta extensión. Si sólo pudiera usar una extensión tendría que elegir esta. Por defecto viene con varias listas activas, pero suelo activar varias más de las que vienen incluidas.  Además, añado la de "I don't care about cookies":

https://www.i-dont-care-about-cookies.eu/abp/

Y también tengo mi propia lista para adecentar varias de las webs que más uso:

https://gist.githubusercontent.com/wodim/22e0bb6fc9615e3f78b21fe90fc08a26/raw/adblock-list.txt

Violentmonkey

Esta extensión permite ejecutar userscripts en páginas. Los userscripts son scripts de JavaScript que llevan una cabecera que dice en qué páginas se deben ejecutar y con qué permisos. Violentmonkey los incluye en las páginas necesarias y una vez allí pueden hacer y deshacer a su antojo.

Escribo userscripts de vez en cuando para facilitar mi navegación. Como ejemplo de lo que un userscript puede hacer, aquí os dejo este que elimina el mensaje que YouTube saca cada vez que abres un vídeo pidiéndote iniciar sesión.


https://stackoverflow.com/a/63803884

Web Archives

Te permite abrir cualquier enlace con WaybackMachine, archive.is y otros proveedores.

Móvil

En el móvil no me gusta complicarme mucho. En iPhone uso Safari con AdGuard como bloqueador de publicidad. En Android ni Chrome ni ninguno de los forks de Chrome permiten instalar extensiones, así es que uso Brave y su bloqueador de publicidad por defecto. No es perfecto, pero no navego mucho en el móvil, así es que me da igual. La versión de Firefox para Android es patética.

Thursday, December 3, 2020

Anotaciones sobre IPv6: Tunnelbroker en una red doméstica

Hace unos meses pusimos fibra en casa con un nuevo ISP y, para dar soporte al número de dispositivos que tenemos y a la nueva velocidad, compré un router nuevo de ASUS bastante tocho. Indagando por el panel de administración vi que había una sección para IPv6, el gran olvidado.

Según había leído "por ahí", este ISP soporta IPv6 nativamente, pero luego vi que no es así. Tienen presencia en muchas localidades de distintos tamaños (en algunas incluso dan servicio por coaxial) y la red está muy segmentada; en mi pueblo todo el mundo pasa por CG-NAT y no hay conectividad IPv6 en absoluto. Tras mucho discutir con ellos conseguí que me diesen una dirección IP pública y estática sin pagar.

Volviendo al router, este tiene soporte para varios sistemas de túneles IPv6, entre ellos 6in4, que es el que ofrece gratuitamente Hurricane Electric mediante Tunnelbroker. Es posible que conozcáis HE por su excelente herramienta, el BGP Toolkit. Recuerdo haber jugueteado mucho en el pasado con los túneles de Tunnelbroker. Con unos cuantos comandos en Linux podías configurar un túnel y acceder a servicios de IPv6. La utilidad era (y es) discutible, puesto que no hay prácticamente ningún servicio a día de hoy que sólo esté disponible mediante IPv6. En cierto modo lo único interesante que se podía hacer con ese túnel era cambiarte la dirección IP constantemente para evadir banes en el IRC hasta que encontrabas a un operador competente.

Las cosas que digo en este artículo están basadas en gran parte en mis observaciones y mi intuición, por lo que pueden no ser correctas. 

Pidiendo y configurando el túnel

Esta parte es sencilla: sólo con registrarte en Tunnelbroker tienes la opción de crear un túnel de manera gratuita. El protocolo 6in4 no tiene ningún sistema de autenticación, por lo que la única manera que tiene el servidor de identificarte es mediante tu dirección IPv4. Por lo tanto, al darte de alta tendrás que especificar tu dirección, ser capaz de responder a ping, y tener en cuenta que si la cambias (por ejemplo, porque tengas dirección IP dinámica) tendrás que usar alguno de estos scripts al estilo dyndns para notificar a Tunnelbroker del cambio.

Debes también elegir un servidor de túnel. No hay ninguno disponible en España, por lo que tus mejores opciones son Portugal y Francia. Junto a cada servidor tienes una dirección IP a la que puedes hacer ping/traceroute/etc. Recuerda que la latencia que tendrás no sólo dependerá de tu latencia con el servidor de túnel sino también de la latencia desde el servidor de túnel al servidor final, por lo que Francia, aun estando un poco más lejos que Portugal, podría ser mejor opción para llegar a servidores de Europa Central.

Una vez creado el túnel llegarás a una pantalla con información sobre tu túnel. Es esa la configuración que tendrás que introducir en el panel del router. En este lamentable collage hecho con Paint muestro la equivalencia de las opciones:

Si te has fijado, en la pantalla de información del túnel tienes la opción de pedir un prefijo /48. No es estrictamente necesario, pero lo puedes hacer si te apetece. Rellenar los servidores DNS es opcional (no aparecen en la captura, pero están más abajo). El servidor DNS de IPv4 que estés usando debería responder con los registros AAAA, pero si no lo hace, puedes o bien cambiar a otro servidor DNS de IPv4 que sí lo haga o rellenar los DNS de esta página con el contenido del campo "Anycast IPv6 Caching Nameserver" del túnel.

El router se reiniciará (o no, depende por dónde le dé) y el túnel debería estar funcionando. Lo podemos comprobar usando cualquier web como Test your IPv6, donde deberíamos obtener una puntuación de 10/10.

Uso de IPv6 en la red doméstica: privacidad, direcciones permanentes y temporales

Una de las promesas de IPv6, quizá la principal, es olvidarnos de los puñeteros sistemas de NAT que estamos obligados a usar debido a la escasez de direcciones IP. Lo que quiere esto decir es que ahora todos los dispositivos que están en tu red local tendrán una dirección IP pública (más bien varias, ahora lo veremos) que es accesible para el resto del mundo.

El uso de NAT, CG-NAT y direcciones IP dinámicas ha complicado tradicionalmente el rastreo de los usuarios mediante sus direcciones IP, pero con las direcciones únicas de IPv6, se origina un posible problema de privacidad y seguridad.

(El resto de esta sección está muy, muy simplificado y no es totalmente correcto, pero es lo suficientemente correcto para el nivel del artículo y para no perderme en los detalles).

Como todos sabemos cómo se obtiene una dirección IP con DHCP bajo IPv4 me voy a ahorrar esa parte. Las conexiones residenciales que dan soporte a IPv6, a grandes rasgos, funcionan mediante prefix delegation: tu router habla con tu ISP para recibir un prefijo usando NDP, y luego comunica dicho prefijo a los equipos de tu LAN usando SLAAC. Una vez tus equipos conocen el prefijo que pueden usar, son libres de asignarse las direcciones IPv6 que quieran: una o varias y del valor que les venga en gana.

Antiguamente, muchos equipos tenían la costumbre de usar una sola dirección IPv6 y encima basarla en la dirección MAC de la tarjeta de red, con las implicaciones obvias. Hoy día, lo común en los equipos modernos es que usen dos direcciones IPv6 distintas: la dirección permanente o pública y la dirección temporal, sistema más o menos descrito en el RFC de IPv6 Privacy Extensions. Si usas Windows, puedes ver ambas usando el comando netsh interface ipv6 show addresses:

Interface 8: Wi-Fi

Addr Type  DAD State   Valid Life Pref. Life Address
---------  ----------- ---------- ---------- ------------------------
Public     Preferred        9m58s      9m58s 2001:470:c8f9:0:xxxx:yyyy:zzzz:aaaa
Temporary  Preferred        9m58s      9m58s 2001:470:c8f9:0:a53b:cf29:a6af:e8f3
Other      Preferred     infinite   infinite fe80::xxxx:yyyy:zzzz:aaaa%8

Es decir:

  • La dirección pública o permanente, que está generada de manera pseudo-aleatoria y es única para la tarjeta de red y la red a la que estás conectado. Esta dirección no cambia nunca bajo circunstancias normales, aunque pase el tiempo o reinicies el ordenador o el router. Esta dirección no se usa por defecto para hacer conexiones salientes pero puede recibir conexiones entrantes en todo momento (depende del firewall de tu router, luego hablaré de ello).
  • La dirección temporal, que está generada de manera aleatoria y cambia a intervalos regulares (normalmente un día, pero depende del sistema operativo y su configuración) y cada vez que reconectas a la red. Esta es la dirección que se usa por defecto para conectar a otros equipos (es decir, la que aparecerá si pones en Google "what's my ip", o la que sale cuando entras al IRC) y también puede recibir conexiones entrantes (una vez más, dependiendo del firewall).
  • La dirección de enlace local, que sólo es válida dentro de tu LAN. El %8 se refiere a tu tarjeta de red (ya que si tienes varias, tendrás varias direcciones de enlace local y todas comienzan por fe80).

Si te has fijado bien, ambas direcciones públicas comienzan por 2001:470:c8f9. Esto es así porque ese es el prefijo /48 que mi ISP me ha delegado (bueno, en este caso, Tunnelbroker). Y si te has fijado aún mejor, la dirección de enlace local es igual que la pública cambiando el prefijo de mi ISP por fe80.

De todo esto desprendemos:

  • Ya que la dirección permanente no cambia, conviene no divulgarla a no ser que sea estrictamente necesario. El sistema no la usa por defecto para realizar conexiones salientes, pero puede recibir conexiones entrantes por ella.
  • Si queremos recibir conexiones, tendremos que usar la dirección permanente, ya que la temporal se renueva constantemente y no podremos recibir más conexiones en cuanto esto ocurra. También tenemos la opción de usar direcciones estáticas manuales (más adelante hablaré de ello).
  • El hecho de que se renueve la dirección temporal no quiere decir que todas las conexiones que la estén usando se interrumpan. Si a la hora de renovar la dirección hay conexiones abiertas, dicha IP seguirá existiendo hasta que dichas conexiones se cierren, pero se generará una IP nueva igualmente que se usará para las nuevas conexiones.
    En la salida del comando que he puesto antes se mostrarían también las direcciones que están esperando para morir (en el ejemplo de arriba no hay ninguna).

Direcciones estáticas manuales y firewall

Como dije antes, si bien lo normal es tener dos, cualquier dispositivo puede tener tantas direcciones IP asignadas como quiera. Al contrario que en IPv4, no es el router (mediante el servidor DHCP) el que decide qué dirección va a usar el dispositivo sino el propio dispositivo, por lo que la necesidad de usar direcciones estáticas se desvanece, pero es posible tenerlas si así lo deseas. Por ejemplo, si tienes varios sistemas operativos o si quieres que conteste un dispositivo distinto dependiendo de cuál esté conectado.

El comando para añadir una dirección nueva es netsh interface ipv6 add address Wi-Fi address=ffff:2/64. En mi caso, tal y como vi antes, mi prefijo es 2001:470:c8f9 con longitud 48 por lo que para añadir una IP estática puedo escribir: netsh interface ipv6 add address Wi-Fi address=2001:470:c8f9::1234. Si usamos el comando de "show addresses" que vimos antes podremos ver esta nueva dirección IP junto a la permanente y la temporal.

Como dije más atrás, por defecto el sistema sólo usa la dirección temporal para realizar conexiones salientes. ¿Qué pasa si queremos que las conexiones salientes usen la dirección permanente o una dirección manual? Muchos programas te lo permiten en las opciones. Por ejemplo, el cliente de BitTorrent uTorrent:

Gracias al NAT, no estamos muy acostumbrados a tratar con sistemas de firewall en la configuración de los routers. Lo que coloquialmente conocíamos como "abrir los puertos" no suponía manipular las opciones de un firewall sino crear una redirección de NAT. En IPv6, al ser todas las direcciones públicas, sí se hace necesario un firewall en el router para las conexiones entrantes. En este caso, creo una sencilla regla para permitir conexiones hacia mi servidor HTTP:

Al tratarse de un firewall y no una NAT, es posible abrir el mismo puerto "varias veces". Es decir, no hay problema en tener el puerto 80 abierto en varios dispositivos a la vez, ya que las conexiones no pasan por el NAT sino que van directamente a los equipos. Para comprobar que la regla está bien puesta puedes usar el IPv6 Online Port Scanner (recuerda introducir la dirección IP que añadimos manualmente y no la que te aparecerá en la web, que es la temporal).

Conclusión

No hay.