? Editing: Post:21.body Save Delete Cancel
Content changed Sign & Publish new content

Today I Learned

We constantly learn new things
This is @ks' repo to
share those learnings

Follow in NewsfeedFollowing

Latest comments:

[Python] Leap second poppycock

on Dec 31, 2016 ·
2 comments

So, tonight we're supposed to insert an extra second 🡕 after 23:59:59 UTC, effectively giving us 23:59:60 before we reach midnight. It seems Python doesn't agree:

#!/usr/bin/python3

from datetime import (datetime, timedelta)
from pytz import UTC
from sys import stderr

try:
    leap = datetime(2016, 12, 31, 23, 59, 60, tzinfo=UTC)
except ValueError as error:
    print(str(error), file=stderr)
    leap = datetime(2016, 12, 31, 23, 59, 59, tzinfo=UTC)
    leap += timedelta(seconds=1)

print('{:%FT%T%z}'.format(leap))

# eof

Let's try:

$ python3 leapsectest.py
second must be in 0..59
2017-01-01T00:00:00+0000

Poppycock! 😒

Read more

[Python] Not everything is an object

on Nov 02, 2016 ·
2 comments

Next time somebody tells you that everything in Python is an object, call bullshit:

>>> [m for m in dir(7) if not m.startswith('__')]
['bit_length',
 'conjugate',
 'denominator',
 'from_bytes',
 'imag',
 'numerator',
 'real',
 'to_bytes']
>>> 7.to_bytes(1, 'big')
  File "<stdin>", line 1
    7.to_bytes(1, 'big')
             ^
SyntaxError: invalid syntax
>>> i = 7
>>> i.to_bytes(1, 'big')
b'\x07'
>>>
Read more

IPv6 privacy extensions and systemd-networkd

on Sep 02, 2016

By default, systemd-networkd generates IPv6 addresses based on the interface's MAC address, which is undesirable. Here's how to have it generate dynamic addresses using SLAAC without disclosing MAC addresses.

To enable privacy extensions for all interfaces add the following to sysctl:

# /etc/sysctl.d/25-ipv6.conf
net.ipv6.conf.all.use_tempaddr=2
net.ipv6.conf.default.use_tempaddr=2

My Raspberry Pi 2 uses eth0 as its network interface and for some reason I need to explicitly mention eth0 in said conf:

net.ipv6.conf.eth0.use_tempaddr=2

Then instruct systemd-networkd to obey the kernel settings:

; /etc/systemd/network/enp3s0.network

[Match]
Name=enp3s0

[Network]
DHCP=yes

IPv6PrivacyExtensions=kernel
Read more

Zeronet behind Caddy with TLS

on Aug 31, 2016

Back in March I couldn't seem to run Caddy 🡕 in front of Zeronet because of websocket troubles. Either Caddy has been improved since then or @keith­irwin found the solution. Either way, here's how:

zero.example.net {
  # Enable HSTS
  header / Strict-Transport-Security "max-age=31556926"
  tls {
    key_type p384
  }
  proxy /          http://127.0.0.1:43110 {
    transparent
  }
  proxy /Websocket http://127.0.0.1:43110 {
    websocket
  }
  # We don't want the world to access our private instance
  basicauth myUsername myPassword {
    /
  }
}

And contrary to the documentation, it is unnecessary to disable HTTP/2 (something that would sadly affect all domains served).

With this configuration Caddy will

  • obtain a certificate from Let's Encrypt 🡕
  • serve all requests to zero.example.net over TLS

So now I can access my Zeronet from everywhere.

Caveat:
Caddy doesn't seem to be quite stable here. Very often Caddy exits with this error:

Aug 31 10:15:06 home caddy[20251]: panic: not a Flusher
Aug 31 10:15:06 home caddy[20251]: goroutine 106 [running]:
Aug 31 10:15:06 home caddy[20251]: panic(0xcac000, 0xc420495e30)
Aug 31 10:15:06 home caddy[20251]:     /usr/local/go/src/runtime/panic.go:500 +0x1a1
Aug 31 10:15:06 home caddy[20251]: github.com/mholt/caddy/caddyhttp/httpserver.(*ResponseRecorder).Flush(0xc4205e54f0)
Aug 31 10:15:06 home caddy[20251]:     /tmp/custombuild_6580_159870072/src/github.com/mholt/caddy/caddyhttp/httpserver/recorder.go:87 +0xda
Aug 31 10:15:06 home caddy[20251]: github.com/mholt/caddy/caddyhttp/proxy.(*maxLatencyWriter).flushLoop(0xc420612540)
Aug 31 10:15:06 home caddy[20251]:     /tmp/custombuild_6580_159870072/src/github.com/mholt/caddy/caddyhttp/proxy/reverseproxy.go:378 +0x156
Aug 31 10:15:06 home caddy[20251]: created by github.com/mholt/caddy/caddyhttp/proxy.(*ReverseProxy).copyResponse
Aug 31 10:15:06 home caddy[20251]:     /tmp/custombuild_6580_159870072/src/github.com/mholt/caddy/caddyhttp/proxy/reverseproxy.go:247 +0x2e1

The bug has been reported as issue #1083 🡕.

Update:
The solution is to not enable QUIC.

Read more

[Misc] Plant nutrient deficiency chart

on May 23, 2016 ·
2 comments

Plant nutrient deficiency chart
(Found on Twitter with no reference to the source.)

Read more

[Security] Enabling HSTS on Caddy

on May 22, 2016

Move from an A to an A+ server rating on SSL Labs:

example.com {
  header / "Strict-Transport-Security", "max-age=31556926; includeSubDomains"

}

For long-running domains you can add a preload to the stanza:

example.com {
  header / "Strict-Transport-Security", "max-age=31556926; includeSubDomains; preload"

}

Then add the domain to the HSTS preload list 🡕

See also

Read more

[Misc] Easily confused glyphs

on May 18, 2016 ·
2 comments

Looking for a good coding font? Cat this file in your terminal.

Easily confused glyphs

  • b69B8Ø0Oo
  • 1Il|
  • ij
  • 5S
  • 2Z
  • 9gq
  • co
  • rn m
  • cl d
  • vv w
  • .,
  • :;
  • `'
  • ''"
  • ' and ‘’ (curved/smart/curly single quotes)
  • " and “” (curved/smart/curly double quotes)
  • ~-
  • – — (n-dash, m-dash)
  • {[()]}
  • u and µ (mu)
  • v and ν (nu)

Uppercase vs. lowercase letters

  • Ww
  • Xx
  • Zz
  • Vv
  • Uu
  • Cc
  • Ss
Read more

[Python] Anaconda cleanup

on Apr 29, 2016
$ conda clean -tp   # t = tarballs, p = unused packages

Cleaned out just short of 1 GB of disk space.

Read more

[Security] Generating new Diffie-Hellman groups

on Apr 12, 2016
$ ssh-keygen -G moduli-2048.candidates -b 2048
$ ssh-keygen -T moduli-2048 -f moduli-2048.candidates

Then install the generated moduli-2048 file as /etc/ssh/moduli.

Update
Generating and verifying 2048, 3072, …, 8192 bits moduli will take days (if not weeks).

2 Ton Digital runs a public DH parameter service 🡕 with a straight-forward API.

Read more

[Security] TLS Interposer and Zeronet

on Apr 09, 2016

TLS Interposer 🡕 is not a new piece of software. However, I thought it would be interesting to learn about Zeronet's choice of TLS ciphers with and without TLS Interposer.

Without TLS Interposer

Grabbing data from the /Stats page I found that almost 9 out of 10 connections were using the ECDHE-RSA-AES128-GCM-SHA256 cipher suite that sports medium-high grade encryption and forward secrecy, while close to 1 out of 10 were using a cipher suite that doesn't support forward secrecy:

     91 ECDHE-RSA-AES128-GCM-SHA256
     12 AES128-GCM-SHA256
      1 AES256-SHA

With TLS Interposer

Next I installed the TLS Interposer library 🡕 and started Zeronet with a few simple requirements:

export LD_PRELOAD='/usr/local/lib/tlsinterposer.so'
export TLS_INTERPOSER_CIPHERS='kEECDH:kEDH:!aNULL:!eNULL:!EXPORT:!MEDIUM:!LOW:!3DES:!MD5:!EXP:!PSK:!SRP:!DSS:!RC4:!SSLv3:!TLSv1'
export TLS_INTERPOSER_OPTIONS='+sorder'
python2 zeronet.py

or, in common language:

  1. Mandatory ephemeral key agreement (“kEECDH:kEDH”)
  2. Use only high grade encryption (“!EXPORT:!MEDIUM:!LOW”)
  3. Drop obsolete protocols (“!SSLv3:!TLSv1”)
  4. Let me decide the cipher order (“+sorder”)

The results?

    128 ECDHE-RSA-AES256-GCM-SHA384
     12 tls-rsa

I frankly don't know what the tls-rsa thing stands for (if you do, please chime in below), but the rest of the connections have been upgraded so that all are using the ECDHE-RSA-AES256-GCM-SHA384 cipher suite, meaning AES256 encryption instead of AES128, and SHA384 hashing instead of SHA256, and of course forward secrecy.

The downside of all this is that if a peer doesn't support any of the protocols and ciphers you're offering, then no connection can be established.

With the restrictions I set on TLS_INTERPOSER_CIPHERS my Zeronet node now offers the following ciphers:

$ openssl ciphers -v "${TLS_INTERPOSER_CIPHERS}"
ECDHE-RSA-AES256-GCM-SHA384   TLSv1.2 Kx=ECDH Au=RSA   Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA384       TLSv1.2 Kx=ECDH Au=RSA   Enc=AES(256)    Mac=SHA384
ECDHE-ECDSA-AES256-SHA384     TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(256)    Mac=SHA384
ECDHE-RSA-AES128-GCM-SHA256   TLSv1.2 Kx=ECDH Au=RSA   Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-SHA256       TLSv1.2 Kx=ECDH Au=RSA   Enc=AES(128)    Mac=SHA256
ECDHE-ECDSA-AES128-SHA256     TLSv1.2 Kx=ECDH Au=ECDSA Enc=AES(128)    Mac=SHA256
DHE-RSA-AES256-GCM-SHA384     TLSv1.2 Kx=DH   Au=RSA   Enc=AESGCM(256) Mac=AEAD
DHE-RSA-AES256-SHA256         TLSv1.2 Kx=DH   Au=RSA   Enc=AES(256)    Mac=SHA256
DHE-RSA-AES128-GCM-SHA256     TLSv1.2 Kx=DH   Au=RSA   Enc=AESGCM(128) Mac=AEAD
DHE-RSA-AES128-SHA256         TLSv1.2 Kx=DH   Au=RSA   Enc=AES(128)    Mac=SHA256
$ # “Kx” = key exchange, “Au” = authentication, “Enc” = encryption

Am I being too restrictive?

See also

Read more

[Misc] Creating a vanity .onion address

on Mar 28, 2016 · 1 min read
$ git clone https://github.com/ReclaimYourPrivacy/eschalot
$ cd eschalot
$ make
$ ./eschalot -p glass
----------------------------------------------------------------
glassr3cwpp4tdb3.onion
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDrtTY+t0kszMmy+UdKEnYON++ZKSGTL+C0FjHKvpoRQxPcNB84
oE/DOhARW68O0lSxnXAXVrCviwTlPyrj5vpSmbZJeuVVh5gM4FJY+kVcVRCb7T8j
B3xJrzQtF2YRhIgQVttuVaOVyydaUGLh1ysvsKHFd6+tOpkZ8CBpqs5FgwIEAcrJ
EwKBgDDYUr5Rjpacc3D8fW/jrwyRy4SPAoyJhroHItxt7c6KKLERQu4w6l1m7kKm
lEMFq3/6lZsQW2gxwCZT8sBrwOhuLsSsxUYZc/9Xzu1Yxp8QOBc8nyl9dJKg1i6m
dp1svaplrraWQ3PBpVelxkilge+hyJi5290E/fdbz9ry6FzbAkEA9ljaWdgtGbm2
bDRpZ5yMpQTAFaGphrgR5rfvPtvjdP1e7SGGPkyW1pOiuueMyarqtkwfpuSAT+Eo
uitLoN7xmwJBAPTxop06MJ290JdDqlr6z9QVQ8JSSobqGJbdpndjqW1x/q9YyoC2
bRb6MGYISmZpMI9DikO99HIcNO9nUeEcDjkCQE0dzFxvcKlRm51zvxxBNtuAuk9F
Op+NSIoUOneMwVVeluFBoTBO6djYJRGOmfVIM/+RS1Yt8Ga0El9roKFjLW0CQHWs
HdqhEiOnfgv7isanlmKyFuKMqRXymiNQWtWNxAqZHmggOCPamffK1iNDDtb1+H8P
BewVqhTLtGV90jajBXMCQQCdfGsNcMjzPGIT8oIYCM6WYti1bbsiUq/q11OjJhJJ
K44hzPmDXpFwgtQjWbJanEV0jrYPD7L4aC7EoxGFGtlB
-----END RSA PRIVATE KEY-----

Usage

Usage:
eschalot [-c] [-v] [-t count] ([-n] [-l min-max] -f filename) | (-r regex) | (-p prefix)
  -v         : verbose mode - print extra information to STDERR
  -c         : continue searching after the hash is found
  -t count   : number of threads to spawn default is one)
  -l min-max : look for prefixes that are from 'min' to 'max' characters long
  -n         : Allow digits to be part of the prefix (affects wordlist mode only)
  -f filename: name of the text file with a list of prefixes
  -p prefix  : single prefix to look for (1-16 characters long)
  -r regex   : search for a POSIX-style regular expression

Examples:
  eschalot -cvt4 -l8-12 -f wordlist.txt >> results.txt
  eschalot -v -r '^test|^exam'
  eschalot -ct5 -p test

  base32 alphabet allows letters [a-z] and digits [2-7]
  Regex pattern examples:
    xxx           must contain 'xxx'
    ^foo          must begin with 'foo'
    bar$          must end with 'bar'
    b[aoeiu]r     must have a vowel between 'b' and 'r'
    '^ab|^cd'     must begin with 'ab' or 'cd'
    [a-z]{16}     must contain letters only, no digits
    ^dusk.*dawn$  must begin with 'dusk' and end with 'dawn'
    [a-z2-7]{16}  any name - will succeed after one iteration
Read more

[BOFH] Taming the log of PyBitmessage

on Mar 26, 2016

PyBitmessage's 🡕 default logging is extremely verbose and logs messages that are irrelevant to the casual user. The mailchuck fork v0.5.4 suggests you take a look at Python's logging config documentation 🡕, which I didn't find helpful, at all: PyBitmessage kept logging to debug.log even after I thought I had replaced all handlers with the NullHandler, and it also complained about missing sections, keys, handlers, formatters, and whatnot.

Luckily, Peter Šurda came to the rescue with two working logging.dat examples 🡕 that I will copy here for the record:

Logging entirely disabled (modified slightly from the original):

[loggers]
keys=root,syslog

[handlers]
keys=syslog

[formatters]
keys=syslog

[logger_root]
level=WARNING
handlers=syslog

[logger_syslog]
level=WARNING
handlers=syslog
qualname=default
propagate=0

[handler_syslog]
class=logging.NullHandler
formatter=syslog
level=WARNING
args=()

[formatter_syslog]
format=%(asctime)s %(threadName)s %(filename)s@%(lineno)d %(message)s
datefmt=%F %T

Logging to remote syslog:

[loggers]
keys=root,syslog

[logger_root]
level=NOTSET
handlers=syslog

[logger_syslog]
level=DEBUG
handlers=syslog
qualname=default
propagate=0

[handlers]
keys=syslog

[handler_syslog]
class=logging.SysLogHandler
formatter=syslog
level=DEBUG
args=(('10.0.0.123', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_LOCAL7)

[formatters]
keys=syslog

[formatter_syslog]
format=%(asctime)s %(threadName)s %(filename)s@%(lineno)d %(message)s
datefmt=%b %d %H:%M:%S

Download the first logging.dat example, stick it in the same directory as your keys.dat file, then restart PyBitmessage.

Read more

[CC] Mitigating Namecoin's 520 bytes limitation

on Mar 25, 2016 ·
1 comments

Problem

You have almost reached Namecoin's 520 bytes data limitation, but you would
like to also include, say, your NXT address, your Signal fingerprint and
your TOX id.

Solution

  1. Trim your current id/ record so that there's room for an import statement.
  2. Create an idd/ (identity data) record with the data that won't fit in the id/ record.

Sample id/abcy with import statement [1]:

{
  "name": "Abe Cyprian",
  "gender": "male",
  "birthday": "1945/01/23",
  "description": "Fortune favours the lucky",
  "locality": "Abukko City",
  "country": "XY",
  "email": "abcy@example.net",
  "gpg": {
    "v": "pka1",
    "fpr": "40352A7A5F88E7D294D4ABC7600A0B36221FD119",
    "uri": "https://abcy.example.net/abcy-pubkey.asc"
  },
  "weblog": "https://blog.example.net/",
  "bitmessage": "BM-NBUWTz8bYadwEbmx6eQZznsj1NeJtp9c",
  "bitcoin": "1ABCYi8DHwj6MuTaogryeqeyym9gbHDu9Z",
  "namecoin": "NABCYawDVg5xM5zrzjvCueuzzY51f5cjh1",
  "import": "idd/abcy"
}

Sample idd/abcy with extra information [2]:

{
  "nxt": {
    "alias": "abcy",
    "account": "NXT-ABC7-7F92-SVFL-5QUWT",
    "pubkey": "55f5b9fd65b0587193f1aecbfedb1d387e40f7e14d3b83c509b94e1db1da6515"
  },
  "signal": "0D08B1EDC6A1C0FDD30D210784ABC7AE2949D5F58768B18B9C2906724B4248595C2",
  "tox": "0C834AE7634ABC78ECBB14A8119AED80C21FB703E97DA43F8FBD237BFFE9109A1A49E776D371"
}

Same method goes for extending a d/ record with a dd/ record (domain data).

Partly unsolved questions

Can idd/ and dd/ records in turn hold import statements? Or should multiple data records be included in the originating record as a list?

{
  "import": [
    "idd/2dac23e0-901b-4103-b991-5eec17e62747",
    "idd/6aa006ef-a0ad-4d56-a266-aca65ac173ec"
  ]
}

The Namecoin wiki 🡕 is not clear on this. Please chime in below if you have the answer – preferrably with a reference.

Update: User qpm on #namecoin @ Freenode IRC says about the matter:

an idd/ name can import another idd/ name. Some clients impose a maximum depth of such import chains. Off the top of my head, I think a common depth limit is 5, but since this part of the spec isn't really finalized, it's possible that the depth limit will change at some point.

and continues:

I think we intend to allow an import statement to contain a list, but I have no idea if current software supports that properly. Using a chain is probably going to be more reliable with current software.

Links

  1. id/abcy 🡕
  2. idd/abcy 🡕

See also

Read more

[Life] The origin of monsters

on Mar 24, 2016 ·
2 comments

“Every monster starts off as someone's baby.”
    ~Cameron in Continuum, S2E9

Read more

[Python] Finding the size of the terminal

on Mar 24, 2016

The documentation 🡕 suggests that shutil.get_terminal_size() be used:

>>> import shutil
>>> tsize = shutil.get_terminal_size()
>>> tsize
os.terminal_size(columns=191, lines=60)
>>> tsize.columns
191
>>> tsize.lines
60
>>>

shutil.get_terminal_size() and os.get_terminal_size() both require Python 3.3+.

shutil.get_terminal_size() examines the environment varables LINES and
COLUMNS, and secondarily uses os.get_terminal_size() to find the size
of stdout.

If you wish to take into account stdin, stdout, stderr, as well as
/dev/tty, use something like this:

#!/usr/bin/python
"""Based on https://stackoverflow.com/a/566752"""

import sys
import os

from fcntl import ioctl
from termios import TIOCGWINSZ
from struct import unpack


def get_terminal_size():
    """Find the size of the terminal"""
    def ioctl_gwinsz(fdsc):
        """…"""
        try:
            packed = ioctl(fdsc, TIOCGWINSZ, bytes(4))
            rowcol = unpack('hh', packed)
        except OSError:
            # Hopefully, this is an
            #     OSError: [Errno 25] Inappropriate ioctl for device
            return
        return rowcol
    rowcol = ioctl_gwinsz(sys.stdin.fileno()) \
        or ioctl_gwinsz(sys.stdout.fileno()) \
        or ioctl_gwinsz(sys.stderr.fileno())
    if rowcol is None:
        try:
            with open(os.ctermid(), 'r') as fptr:
                rowcol = ioctl_gwinsz(fptr.fileno())
        except OSError:
            pass
    if rowcol is None:
        rowcol = (
            os.environ.get('LINES', 25),
            os.environ.get('COLUMNS', 80)
        )
    return map(int, rowcol)

if __name__ == '__main__':
    (LINES, COLUMNS) = get_terminal_size()
    # Similar to the output from resize(1)
    print('COLUMNS={}; export COLUMNS;'.format(COLUMNS))
    print('LINES={}; export LINES;'.format(LINES))

# eof
Read more
Add new post

Title

21 hours ago · 2 min read ·
3 comments
Body
Read more

Title

21 hours ago · 2 min read

0 Comments:

user_name1 day ago
Reply
Body
This page is a preview of ZeroNet. Start your own ZeroNet for complete experience. Learn More