Compare commits
14 Commits
8b0a3cb9c0
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
932c9adc52
|
|||
|
d9e78012e8
|
|||
|
8b4b46f283
|
|||
|
b1c028a8d0
|
|||
| 60b4196747 | |||
| b70dc3e07d | |||
| decfba6bd8 | |||
| a69915b46d | |||
| ba567e0d65 | |||
| 98cfbaf97c | |||
| 949563452b | |||
| 3faa38c729 | |||
| 4728bd16c8 | |||
| 6ae9a414b3 |
@@ -1,103 +0,0 @@
|
|||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Looks bad. And it is! Workaround for having no control over
|
|
||||||
* how the markdown python module renders the post.
|
|
||||||
*/
|
|
||||||
.post > article > p > img {
|
|
||||||
/* Prevent images in blog posts from getting too big */
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.profile-picture {
|
|
||||||
max-width: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1, h2, h3, h4 {
|
|
||||||
color: #9b59b6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-list {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-list-item {
|
|
||||||
display: block;
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post-list-item-title {
|
|
||||||
color: #3498db;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
font-size: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
font-size: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-content {
|
|
||||||
max-width: 1000px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stretch-horizontally {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 768px) {
|
|
||||||
.page-title {
|
|
||||||
/* The page header title otherwise overflows the page on small screens */
|
|
||||||
font-size: 8vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-content {
|
|
||||||
/* Otherwise the page content overflows the page */
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text {
|
|
||||||
/* A smaller font looks better on smaller devices */
|
|
||||||
font-size: 19px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.post {
|
|
||||||
/* A smaller font looks better on smaller devices */
|
|
||||||
font-size: 19px;
|
|
||||||
|
|
||||||
/* Otherwise the entire page overflows for some reason */
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
p > img {
|
|
||||||
/* This should match all images used inside blog posts */
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0 3px;
|
|
||||||
border-radius: 3px;
|
|
||||||
|
|
||||||
background-color: black;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre > code {
|
|
||||||
background-color: black;
|
|
||||||
line-height: 1.5;
|
|
||||||
border-radius: 3px;
|
|
||||||
|
|
||||||
padding: 10px;
|
|
||||||
|
|
||||||
width: 100%;
|
|
||||||
overflow-x: auto;
|
|
||||||
}
|
|
||||||
85
assets/css/code.css
Normal file
85
assets/css/code.css
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
pre { line-height: 125%; }
|
||||||
|
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||||
|
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
|
||||||
|
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||||
|
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||||
|
|
||||||
|
/* From https://github.com/richleland/pygments-css/blob/master/native.css */
|
||||||
|
.codehilite .hll { background-color: #404040 }
|
||||||
|
.codehilite { background: #202020; color: #d0d0d0 }
|
||||||
|
.codehilite .c { color: #999999; font-style: italic } /* Comment */
|
||||||
|
.codehilite .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||||
|
.codehilite .esc { color: #d0d0d0 } /* Escape */
|
||||||
|
.codehilite .g { color: #d0d0d0 } /* Generic */
|
||||||
|
.codehilite .k { color: #6ab825; font-weight: bold } /* Keyword */
|
||||||
|
.codehilite .l { color: #d0d0d0 } /* Literal */
|
||||||
|
.codehilite .n { color: #d0d0d0 } /* Name */
|
||||||
|
.codehilite .o { color: #d0d0d0 } /* Operator */
|
||||||
|
.codehilite .x { color: #d0d0d0 } /* Other */
|
||||||
|
.codehilite .p { color: #d0d0d0 } /* Punctuation */
|
||||||
|
.codehilite .ch { color: #999999; font-style: italic } /* Comment.Hashbang */
|
||||||
|
.codehilite .cm { color: #999999; font-style: italic } /* Comment.Multiline */
|
||||||
|
.codehilite .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */
|
||||||
|
.codehilite .cpf { color: #999999; font-style: italic } /* Comment.PreprocFile */
|
||||||
|
.codehilite .c1 { color: #999999; font-style: italic } /* Comment.Single */
|
||||||
|
.codehilite .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
|
||||||
|
.codehilite .gd { color: #d22323 } /* Generic.Deleted */
|
||||||
|
.codehilite .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
|
||||||
|
.codehilite .gr { color: #d22323 } /* Generic.Error */
|
||||||
|
.codehilite .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
|
||||||
|
.codehilite .gi { color: #589819 } /* Generic.Inserted */
|
||||||
|
.codehilite .go { color: #cccccc } /* Generic.Output */
|
||||||
|
.codehilite .gp { color: #aaaaaa } /* Generic.Prompt */
|
||||||
|
.codehilite .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
|
||||||
|
.codehilite .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
|
||||||
|
.codehilite .gt { color: #d22323 } /* Generic.Traceback */
|
||||||
|
.codehilite .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
|
||||||
|
.codehilite .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
|
||||||
|
.codehilite .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
|
||||||
|
.codehilite .kp { color: #6ab825 } /* Keyword.Pseudo */
|
||||||
|
.codehilite .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
|
||||||
|
.codehilite .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */
|
||||||
|
.codehilite .ld { color: #d0d0d0 } /* Literal.Date */
|
||||||
|
.codehilite .m { color: #3677a9 } /* Literal.Number */
|
||||||
|
.codehilite .s { color: #ed9d13 } /* Literal.String */
|
||||||
|
.codehilite .na { color: #bbbbbb } /* Name.Attribute */
|
||||||
|
.codehilite .nb { color: #24909d } /* Name.Builtin */
|
||||||
|
.codehilite .nc { color: #447fcf; text-decoration: underline } /* Name.Class */
|
||||||
|
.codehilite .no { color: #40ffff } /* Name.Constant */
|
||||||
|
.codehilite .nd { color: #ffa500 } /* Name.Decorator */
|
||||||
|
.codehilite .ni { color: #d0d0d0 } /* Name.Entity */
|
||||||
|
.codehilite .ne { color: #bbbbbb } /* Name.Exception */
|
||||||
|
.codehilite .nf { color: #447fcf } /* Name.Function */
|
||||||
|
.codehilite .nl { color: #d0d0d0 } /* Name.Label */
|
||||||
|
.codehilite .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */
|
||||||
|
.codehilite .nx { color: #d0d0d0 } /* Name.Other */
|
||||||
|
.codehilite .py { color: #d0d0d0 } /* Name.Property */
|
||||||
|
.codehilite .nt { color: #6ab825; font-weight: bold } /* Name.Tag */
|
||||||
|
.codehilite .nv { color: #40ffff } /* Name.Variable */
|
||||||
|
.codehilite .ow { color: #6ab825; font-weight: bold } /* Operator.Word */
|
||||||
|
.codehilite .w { color: #666666 } /* Text.Whitespace */
|
||||||
|
.codehilite .mb { color: #3677a9 } /* Literal.Number.Bin */
|
||||||
|
.codehilite .mf { color: #3677a9 } /* Literal.Number.Float */
|
||||||
|
.codehilite .mh { color: #3677a9 } /* Literal.Number.Hex */
|
||||||
|
.codehilite .mi { color: #3677a9 } /* Literal.Number.Integer */
|
||||||
|
.codehilite .mo { color: #3677a9 } /* Literal.Number.Oct */
|
||||||
|
.codehilite .sa { color: #ed9d13 } /* Literal.String.Affix */
|
||||||
|
.codehilite .sb { color: #ed9d13 } /* Literal.String.Backtick */
|
||||||
|
.codehilite .sc { color: #ed9d13 } /* Literal.String.Char */
|
||||||
|
.codehilite .dl { color: #ed9d13 } /* Literal.String.Delimiter */
|
||||||
|
.codehilite .sd { color: #ed9d13 } /* Literal.String.Doc */
|
||||||
|
.codehilite .s2 { color: #ed9d13 } /* Literal.String.Double */
|
||||||
|
.codehilite .se { color: #ed9d13 } /* Literal.String.Escape */
|
||||||
|
.codehilite .sh { color: #ed9d13 } /* Literal.String.Heredoc */
|
||||||
|
.codehilite .si { color: #ed9d13 } /* Literal.String.Interpol */
|
||||||
|
.codehilite .sx { color: #ffa500 } /* Literal.String.Other */
|
||||||
|
.codehilite .sr { color: #ed9d13 } /* Literal.String.Regex */
|
||||||
|
.codehilite .s1 { color: #ed9d13 } /* Literal.String.Single */
|
||||||
|
.codehilite .ss { color: #ed9d13 } /* Literal.String.Symbol */
|
||||||
|
.codehilite .bp { color: #24909d } /* Name.Builtin.Pseudo */
|
||||||
|
.codehilite .fm { color: #447fcf } /* Name.Function.Magic */
|
||||||
|
.codehilite .vc { color: #40ffff } /* Name.Variable.Class */
|
||||||
|
.codehilite .vg { color: #40ffff } /* Name.Variable.Global */
|
||||||
|
.codehilite .vi { color: #40ffff } /* Name.Variable.Instance */
|
||||||
|
.codehilite .vm { color: #40ffff } /* Name.Variable.Magic */
|
||||||
|
.codehilite .il { color: #3677a9 } /* Literal.Number.Integer.Long */
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/* Generated by python pygmentize, modified by me*/
|
|
||||||
pre { line-height: 125%; }
|
|
||||||
td.linenos pre { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }
|
|
||||||
span.linenos { color: #000000; background-color: #f0f0f0; padding-left: 5px; padding-right: 5px; }
|
|
||||||
td.linenos pre.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
|
||||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
|
||||||
.codehilite .hll { background-color: #ffffcc }
|
|
||||||
.codehilite .c { color: #408080; font-style: italic } /* Comment */
|
|
||||||
.codehilite .err { border: 1px solid #FF0000 } /* Error */
|
|
||||||
.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
|
|
||||||
.codehilite .o { color: #666666 } /* Operator */
|
|
||||||
.codehilite .ch { color: #408080; font-style: italic } /* Comment.Hashbang */
|
|
||||||
.codehilite .cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
|
||||||
.codehilite .cp { color: #BC7A00 } /* Comment.Preproc */
|
|
||||||
.codehilite .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
|
|
||||||
.codehilite .c1 { color: #408080; font-style: italic } /* Comment.Single */
|
|
||||||
.codehilite .cs { color: #408080; font-style: italic } /* Comment.Special */
|
|
||||||
.codehilite .gd { color: #A00000 } /* Generic.Deleted */
|
|
||||||
.codehilite .ge { font-style: italic } /* Generic.Emph */
|
|
||||||
.codehilite .gr { color: #FF0000 } /* Generic.Error */
|
|
||||||
.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
|
||||||
.codehilite .gi { color: #00A000 } /* Generic.Inserted */
|
|
||||||
.codehilite .go { color: #888888 } /* Generic.Output */
|
|
||||||
.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
|
||||||
.codehilite .gs { font-weight: bold } /* Generic.Strong */
|
|
||||||
.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
|
||||||
.codehilite .gt { color: #0044DD } /* Generic.Traceback */
|
|
||||||
.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
|
||||||
.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
|
||||||
.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
|
||||||
.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
|
|
||||||
.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
|
||||||
.codehilite .kt { color: #B00040 } /* Keyword.Type */
|
|
||||||
.codehilite .m { color: #666666 } /* Literal.Number */
|
|
||||||
.codehilite .s { color: #BA2121 } /* Literal.String */
|
|
||||||
.codehilite .na { color: #7D9029 } /* Name.Attribute */
|
|
||||||
.codehilite .nb { color: #008000 } /* Name.Builtin */
|
|
||||||
.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
|
||||||
.codehilite .no { color: #880000 } /* Name.Constant */
|
|
||||||
.codehilite .nd { color: #AA22FF } /* Name.Decorator */
|
|
||||||
.codehilite .ni { color: #999999; font-weight: bold } /* Name.Entity */
|
|
||||||
.codehilite .ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
|
||||||
.codehilite .nf { color: #0000FF } /* Name.Function */
|
|
||||||
.codehilite .nl { color: #A0A000 } /* Name.Label */
|
|
||||||
.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
|
||||||
.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
|
|
||||||
.codehilite .nv { color: #7473CE } /* Name.Variable */
|
|
||||||
.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
|
||||||
.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
|
|
||||||
.codehilite .mb { color: #666666 } /* Literal.Number.Bin */
|
|
||||||
.codehilite .mf { color: #666666 } /* Literal.Number.Float */
|
|
||||||
.codehilite .mh { color: #666666 } /* Literal.Number.Hex */
|
|
||||||
.codehilite .mi { color: #666666 } /* Literal.Number.Integer */
|
|
||||||
.codehilite .mo { color: #666666 } /* Literal.Number.Oct */
|
|
||||||
.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
|
|
||||||
.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
|
|
||||||
.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
|
|
||||||
.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
|
|
||||||
.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
|
||||||
.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
|
|
||||||
.codehilite .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
|
||||||
.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
|
|
||||||
.codehilite .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
|
||||||
.codehilite .sx { color: #008000 } /* Literal.String.Other */
|
|
||||||
.codehilite .sr { color: #BB6688 } /* Literal.String.Regex */
|
|
||||||
.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
|
|
||||||
.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
|
|
||||||
.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
|
|
||||||
.codehilite .fm { color: #0000FF } /* Name.Function.Magic */
|
|
||||||
.codehilite .vc { color: #19177C } /* Name.Variable.Class */
|
|
||||||
.codehilite .vg { color: #19177C } /* Name.Variable.Global */
|
|
||||||
.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
|
|
||||||
.codehilite .vm { color: #19177C } /* Name.Variable.Magic */
|
|
||||||
.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
<!-- title: About "PapaTutuWawa" -->
|
|
||||||
<!-- description: -->
|
|
||||||
<!-- render: yes -->
|
|
||||||
<div class="vertical text">
|
|
||||||
<div class="horizontal-center">
|
|
||||||
<div class="text-content">
|
|
||||||
<h3>About "PapaTutuWawa"</h3>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<img
|
|
||||||
class="profile-picture"
|
|
||||||
src="assets/img/profile.jpg"
|
|
||||||
alt="Profile Picture" />
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="quote">
|
|
||||||
<p>
|
|
||||||
Student, Anime expert, Vocaloid listener, Docker and Linux fan
|
|
||||||
and hobby SysAdmin.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://{{ git_url }}/">Code</a></li>
|
|
||||||
<li><a href="https://{{ blog_url }}/">Blog</a></li>
|
|
||||||
<li><a href="https://{{ mastodon_url }}/">Mastodon</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>Contact</h3>
|
|
||||||
<ul>
|
|
||||||
<li>EMail: <i>{{ email_user }} ["a" with a weird circle] {{ email_domain }}</i> (<a href="https://{{ email_gpg_url}}">GPG</a>)</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<h3>About This Page</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://{{ git_url }}/PapaTutuWawa/blog.polynom.me">Source</a></li>
|
|
||||||
<li>Last updated <i>{{ build_time }}</i></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjaYYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaA5/4P/1SU69isY6/kRRc2VpZ9MYni
|
|
||||||
/pCd1yNtoYYC3yuMij22k7nx1osoEGofjdNiSp15DOZI/RVhKdeppU2BxJ8LuejB
|
|
||||||
wllqjhU5sS2fa9Me0P7Sv33o9jQAUmPKVY3KmdwkNj+/Vd1gmxAYEhoU/9KhzRcF
|
|
||||||
fF1wVFTfFbtRmHan/3yQbW807W2TnkqOi1c6i6PSCgf20H5rHglOdYzKr1+suQ6T
|
|
||||||
nx1+2hYlKzPkMyU9+R21PPdU7+3lUMxuvJ301xIOGD3ri45FHKgg5rpagdJctC1w
|
|
||||||
sVccXQERn0yuU40YHyAmXFy6BOuJk+8Eh7bb/8X/ASpuIjZccyyGlja/h5w3gYYm
|
|
||||||
rni4ApdH+VtNZtSwTb4plxaktgEXiOvIvF0u7z2Xs4J4XPorvjFwq5nZU2A6MeNd
|
|
||||||
hDfdmAOOfjfafgigQRSRbx35YInw45USccE9kyib/YlBDf2snCYXgGqGiREBmehf
|
|
||||||
7tGS10NWidomhn14otlXB/H4kQ8PwjrfpwmDCXPhtCZAQ8g+YF5ynvzjcalQCxEK
|
|
||||||
D1+0ADpmX7Gbz0AXrRu2mSbYJyJD+11+35KOM6mV1BMU8f3VVRB3FIwb8/jcU4T9
|
|
||||||
V+Jcnz2KSjxKS9UXVXeGkXcYPEx3zYXwHOwlzfsLmq7wsvjZKSqqOCSicERP5KA2
|
|
||||||
yZI/9w2nH5fS9S5ZP4rw
|
|
||||||
=4/jw
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -23,7 +23,7 @@ from the device?
|
|||||||
### Getting Output
|
### Getting Output
|
||||||
While preparing myself for this task, I learned that there are a couple of ways.
|
While preparing myself for this task, I learned that there are a couple of ways.
|
||||||
|
|
||||||
One is called [*RAM console*](https://wiki.postmarketos.org/wiki/Mainlining_FAQ#Writing_dmesg_to_RAM_and_reading_it_out_after_reboot). What is does is just dump everything that the kernel prints into a
|
One is called [*RAM console*](https://wiki.postmarketos.org/wiki/Mainlining_FAQ#Writing_dmesg_to_RAM_and_reading_it_out_after_reboot). What it does is just dump everything that the kernel prints into a
|
||||||
reserved region of memory, which can later be retrieved by reading from `/proc/last_kmsg` with a
|
reserved region of memory, which can later be retrieved by reading from `/proc/last_kmsg` with a
|
||||||
downstream kernel.
|
downstream kernel.
|
||||||
|
|
||||||
@@ -94,7 +94,7 @@ the value `"Jig UART On"`:
|
|||||||
|
|
||||||
The keyword `ADC_JIG_UART_ON` seems especially interesting. Why? Well, the driver has to know what to do
|
The keyword `ADC_JIG_UART_ON` seems especially interesting. Why? Well, the driver has to know what to do
|
||||||
with each measured resistance. It would make sense that we call the constant which contains the resistance
|
with each measured resistance. It would make sense that we call the constant which contains the resistance
|
||||||
something like that. Additionally, it is the only constant name name that does not immediately hint at its
|
something like that. Additionally, it is the only constant name that does not immediately hint at its
|
||||||
value or function.
|
value or function.
|
||||||
|
|
||||||
So we search the kernel source for this keyword. Most occurences are just
|
So we search the kernel source for this keyword. Most occurences are just
|
||||||
@@ -139,7 +139,7 @@ connect the phone's D- and D+ lines to the host USB's D- and D+. Hence the need
|
|||||||
conversion for us and also deals with the timing of the data: The tiny board to which all cables lead to
|
conversion for us and also deals with the timing of the data: The tiny board to which all cables lead to
|
||||||
basically just contains an *FT232RL* chip from *FTDI*. It is what does all the conversion and timing magic.
|
basically just contains an *FT232RL* chip from *FTDI*. It is what does all the conversion and timing magic.
|
||||||
|
|
||||||
Since I don't want to accidentally brick by phone my frying it with 3.3V or 5V - though I think that damaging
|
Since I don't want to accidentally brick by phone by frying it with 3.3V or 5V - though I think that damaging
|
||||||
the hardware with 5V is pretty difficult - I did not connect the USB's 5V to the *FT232*'s VCC port.
|
the hardware with 5V is pretty difficult - I did not connect the USB's 5V to the *FT232*'s VCC port.
|
||||||
|
|
||||||
Booting up the device, we start to see data being sent via serial!
|
Booting up the device, we start to see data being sent via serial!
|
||||||
@@ -224,7 +224,7 @@ Device Tree files, the *S7* uses the Exynos 8890 SoC. This one is not in mainlin
|
|||||||
required to port it from the [downstream kernel](https://github.com/ivanmeler/android_kernel_samsung_universal8890/) into mainline.
|
required to port it from the [downstream kernel](https://github.com/ivanmeler/android_kernel_samsung_universal8890/) into mainline.
|
||||||
|
|
||||||
### Device Support
|
### Device Support
|
||||||
The challenge that follows, required I don't brick my phone, is the kernel support for the SoC's hardware.
|
The challenge that follows, provided I don't brick my phone, is the kernel support for the SoC's hardware.
|
||||||
|
|
||||||
#### GPU
|
#### GPU
|
||||||
The GPU of the Exynos 8890 SoC is a Mali-T880 from ARM. While there is no "official" FOSS-driver for it, one
|
The GPU of the Exynos 8890 SoC is a Mali-T880 from ARM. While there is no "official" FOSS-driver for it, one
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaA4dEP/1gdY+0MPilvt2MVVDOpeewZ
|
|
||||||
arHmDLticrsVWnftbGbvNHfRagcqfyPDA4chk7dLFUhTz2DDr7qzvMF2XbY1o0yc
|
|
||||||
hZdElIROcSGJz8OpW/2Cb2+bsH5DOz4RTBHXCAOhAlQnu9OWOScsg0kCwg1dyzfO
|
|
||||||
OdcfFeUAO4JRDjzREZ5JEiI788e3CXt2XP3TVwF82pExYMQt7ii1wQQZXl0hIZmA
|
|
||||||
QhmtUeLs+iUQ1JEnUJZMRDl1iJMxsirEtxAKvOCE/Mtol29j6j+83xrTyDahl1u9
|
|
||||||
ORnxFcznwGm8Mlw0bvFiEIWwAf7hCCYIcLjmh52cfLSrL+CsKOscGR79i6hIBAR9
|
|
||||||
hyYB/jg1Ug35J7eN5Lx2Qj0gf0LcGIzXukuE7PqNONzhDWcTsu43paXD2muSLyi7
|
|
||||||
y7sr1OQWcNbXKbS2+bbRtpJAqphrhdACIcAd8JKaJbQxxjfhETIT3bLUaRsLryZq
|
|
||||||
7CIUKIa/5gx/fqXbovIF7JOIi08ItxKAZtksi+viGZRJgghoVmPJftLcNO8JwZ5Y
|
|
||||||
TtfF03dRFRR72EfXn2glkeCN/XKHkmzKk35XFWdC80LB79cazxRINCjVv+1G4LFp
|
|
||||||
13HCL/MBMku5kOzxoWwb6b7mZSXf26QLRuBXaQd/uCnI5V1Y3RDzMje/Uwcqfpq5
|
|
||||||
9Nwx1i+VdelP7au0L/La
|
|
||||||
=QVca
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAGeIP/0hNo1wq7xXKWYhQUVqk5mNq
|
|
||||||
2sPPfxg3+6KNuidUmxnwIpXsIPEw7jJ3xh74hb6afWHH0ZitrIUoLszkcOkEJaNe
|
|
||||||
Zz+5UfsQybdYbWUsmpJCNK9QKEvwOa7B1TLUeI1ZR6B9KVVIUApg8AEYzBGce5ON
|
|
||||||
MroYc/oQgEZCm5cSmuVc/+yds/gFwvJUmEZOFbXyhl1jGr499fG5Q/khZ0bwPZP5
|
|
||||||
swbUBij0A8nBHiso5k+pDPEUIS6mE6hKZBH+gr9/CefCj1LCyiKRDjeNujZqmiRH
|
|
||||||
r2w/3nARAfr0Vd7X7P/Zsz3iKfP4/SEbHqY6mSGTWyahWajuiJWDMnM6HhIFHXbE
|
|
||||||
RdH1HSDB2bj93TGHaNDwG/4l0FHyqGHmhtVMo243fXJv1zaLlSabTcXFa0wPEToA
|
|
||||||
Z4OQcZWjDzumz2OnbBInaev8Q3aQsvkQERs3jbAw9HaKJqn/tOhPCFqrZRlvyhmV
|
|
||||||
IvcWoPYtqaRA0MCjK7eDlMN1vcllR8owNXLN/xTKoNDPDAKOezalF2NgwNrBDqIM
|
|
||||||
WEQBHRRa3Atm4aAOH8h8SZ+zYO63cmndCdpRA6eSmZ1lOO5NhmN9OfUX/ulLKFP9
|
|
||||||
YEefJ0bfANnz2tjaogWAwQeZYSH5Pj51VvmQnwX5D1taBQXqMJbyMFfdsU45JQNu
|
|
||||||
GYM5qpVHR7NDrj5X4uAG
|
|
||||||
=t56n
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaA91MP+wX5e2v6CuaOEewjOFwhPWa1
|
|
||||||
Naq31RhJvuYD3/leIVy4fZa+EkBgk9QNgnavOeKkM1bHlc6bZggE/sLwnTuhoXFX
|
|
||||||
xSHil8oaF/7rNdgjjNUq8+N3Zo7GSGWJzOyZua/B91mubEDbwF9soqo2mXFzZBC3
|
|
||||||
ZJODsWcK+l3lz9oiNGGxfa3NbkoNRF2falEYckeUoGg84xYknoSx8aGo8cbmyiRO
|
|
||||||
aorTF7NtQMyhMXC4CfSoy/wjit1x+JYa11lr7epF4oy7yx+n0e5b58COkA5AEiL9
|
|
||||||
XGzKe5IfphENj6tL6fnoiO80rXRQ34FaIjSLr/8kwKz/AQ5UIGeRybGPUdTaOz5D
|
|
||||||
u9AVGD5HvLeUdwVilCf5Lhmutu9+0y86HImPoGYS6n7jZApIDelayaRHhmrcYT29
|
|
||||||
yxCxHg9ulKBjq6Owbdqhfyf9oWB2gnHYnM8iD7bvJGkHJlLvIDaSsNyiOJeLs50S
|
|
||||||
hU/UGuAnKRAqHRhZuYhW7Z8NVwxXeJ21lwCF3scxfSn65oAJKwSjIWIXnoEhzRaA
|
|
||||||
hkLiL4Gq22simb/coNn94VC7xvY439Rvaes86ZYaLsyi5lMJUGtOFrmL33v0iCDB
|
|
||||||
FS2l42UtMJxQsRezd8gd7IVRJrJynwymHwpu/8YuNP3n1kzv9cva/B7fsccBS5li
|
|
||||||
1/lQA/A75nkqAqKyO/16
|
|
||||||
=iSmJ
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaACLAP/2b44Gl5t6beFRRTDuwEWTtY
|
|
||||||
q+88M9VFYJqoU9Fmvjeeiz5cdBi4PJRVK+U3He+Mxp8EcL64u3XUsKY6OnVJQ2t5
|
|
||||||
dm1/uWEI8TUIYHGOKyqZtn0TrWUF6NoFsE/KmSWCq307dD0RRtLzDm6ztkE1XoPJ
|
|
||||||
U/NP54ScCHA9StZPMA6UkLqv6pfV42eiCz3c42m4OfhAq4Ch1q5Nyuyh+GokQVA0
|
|
||||||
wFtTLzXbJxJZgRvxLhT2tyBMWn2+kp6TfR6ZGkbzzdSObM7v1Cj5ZY0IVAt5wVQC
|
|
||||||
JEXY5GZ/nyw5zzLyqkZjoDvzlhDCOKz4866uZr87rMAeFpmFb7YKed7sWD/72a8b
|
|
||||||
z2dg+i8HOM7fm2FFffyPVROZ8WS1v3sZBayFQsNCMZ5hCKJfzqsIIUCYwZ6frNJ/
|
|
||||||
BMv4bB5tSjmcEMD+pCQNTnRdqLdlZfRRAVIpwyPGPlzS9y+v6wNniyupM0AkeQii
|
|
||||||
xS5rSXWEBok7Z8hOSX0J206aDDdXVkHhnR80JU3DC3SfDBohAMSfG/9bwnlYBZcS
|
|
||||||
o3/P3q0u1alfKOgCJorb4sq3t2OdHsTrS3MYWgiyLNFKKfQktenAkToSecP0zgXe
|
|
||||||
qVbrCuQmZnFuDjtPh45kEK61i/5YveLfHaZX2unHsja4V/vXPOsinvJVMnBsfEzp
|
|
||||||
1SnNcGw4v1jzT/7Gx8Z3
|
|
||||||
=eW+1
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAymcQAKoksLNNyoEuE4/wzaNv56UA
|
|
||||||
yqg+ylYz0vHnDYPgvawLolkQfrgbKzGa0zN3ugMvHR7sVQxdsT4BqmjSSs0CR1P9
|
|
||||||
aWIfBBoPAB0OzKh7M64/K2vVeok/tbfa2Y5DFYGZbBuKDxJwr40Tfu4kJNk89LZQ
|
|
||||||
KGed9+ZJo8STtdy7VjNL5sQIBMtGfFtNW9cYVR5Fr4uF/m2FKc6zYLXA5t3tbIWD
|
|
||||||
RzIjD1s6GYLeLmj0ZGtgopLWX6ERIAtiveCn+LmPYtU+wsPBOv8Xg8+nQWq6bwpO
|
|
||||||
8WHuQD049MZ/XRmeNnlBcfg7b1TIsZD5fya+rD85sKEXFWs4QMraDeAII+aJoZpd
|
|
||||||
QyDafn7gj37E6ej+Q5qCuh7hsWslC4YaQek0GRlCygz/+Jn+NtnwXaNVEJs22j7V
|
|
||||||
Lj6+2cUExQAX7MySNDdbwyS/PUrYrVLLagx6NW2OdII3UBz+A4srFb9RQ6dttWOE
|
|
||||||
CzTHVY7BX4QalJyjc7Yex5do8lH/PZ23IsCSFE/r0I0kJes2Raq9eTyAISpvQSeZ
|
|
||||||
HfvkiyrW3feOVfSjp64L7Y+lxmtgfo6HJhUZcb21OwlpLYJxRin+QOWHWbeg+fx0
|
|
||||||
0EpJoKETofj8g5ErdZajFezr6odM27M3XGrTJIJJO6OqLv7fUYWc2Xmuf9+DXGTR
|
|
||||||
fjVwJtmEIo/jR92saXgg
|
|
||||||
=OXjT
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAFAEP/0MMomPeqy56TnDjvG+fFEPC
|
|
||||||
PPDexOXD8h0KVBGUdFGS7FPBn/O4ByKVE6Ki/y/2YttBt+P3RceT1eNjY+rPxFu9
|
|
||||||
B7hcjli72G6dZ4bzofbNl3huG4oWmDEpX9CT87lL8vGU/4CqaKIk/dfBxuFPwqus
|
|
||||||
5CyMX/ECMTjRNbQ75EKGE4vINht45pWFLzZUp+DKw4K2idOaQ8T+8vAKF0o10/Qr
|
|
||||||
npDCAy0hIY9HWmYEI7JheUfMrw5jxYJ6vXIGHmsiVqX8DXxGpXXqevDhkFa6QEbA
|
|
||||||
sgENJr5EvCR2ZeM3e566qYXSibCSfq58aXEVkt9yXrNrj0Q7Iz/uD7J5lR64e+rD
|
|
||||||
Hv43p/lKbFRi7UAYpWR8nUXSX8wbzTETgT/WUeExD0AWIsyYAj33R7U1UngCL9qI
|
|
||||||
IrkrPKnxBFRQTxl6v+MxEN7xAtKf9BWtbm+VQv+xuPtIE1dUof6oUKGA+f9qFrnR
|
|
||||||
XucIZrGNbOfwfJ3P4w+crvI2WgqvH7vQSJbQPKNEXvQP9rYh5L7nG1IXqaHRQnuO
|
|
||||||
kn9EcG/uQOkZUeo+8uvBJvSmcE9DiyYFfWvoDvpqtMfdolD+n8HXNfGFaGkHZ7+b
|
|
||||||
RgFWmIGshVZo968y6iP9zyubdViF5JWl8r4pR6Y9MIbjiXOfgTPMpYpFL7lJQ2kr
|
|
||||||
S1EEc4E/Axw0VYSk2jTw
|
|
||||||
=WyMf
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
-----BEGIN PGP SIGNATURE-----
|
|
||||||
|
|
||||||
iQJMBAABCAA2FiEEvBU+39pRCqHFhwUCToYVYy9G5oAFAmGjjakYHHBhcGF0dXR1
|
|
||||||
d2F3YUBwb2x5bm9tLm1lAAoJEE6GFWMvRuaAE28P/0MZqiLeSDVP+W8eKaXrWh5i
|
|
||||||
BfKDbRefdtV8/Ybs0MSCU9FyRv/PAvN7uA6KsBwptyJD8YMcJt1f8npjjN/E4In6
|
|
||||||
uHz3EjjQmM5h4GIvnchN6IKL0CzkZspLH7thd5HXDYey7iEnu/b2P3W8MGdJbBYx
|
|
||||||
x9dnGTDLm0y+x5FV8Lpe/UCgL1xTli0lpmUMKqzg58WFtrU2YD0y6jircxOKxyeO
|
|
||||||
Rp0Sb2G/vfZL9oKVdK28zZ6CINCmNbYTaI/tqwTxoM9tB/+He+H4RaiAfFzU2/Ri
|
|
||||||
jOm48xwr2Vmx2jvBk6mvQppIRtmy5tUOB9pFSTjQBCHL3hBUbN/nImAhpDl5u7CQ
|
|
||||||
Y1xK60i42YFyiOj6vD551XoQNmgiJ7zVuJ3wy+k03wl1RujbRxnPkm2vwhPVPBBL
|
|
||||||
1IWxoUPyTwpD6f/td2sZdqYGa8H+lRx8hjzwAw55zCF6KdCvLSWz6DBZUrQo1Wji
|
|
||||||
nwVHcOtidfo3l9fH3xR8tshM2Rsv6XuKtyp3WkLJajW0r2et/bAyz29oU0BtGUlE
|
|
||||||
dmjhCllGgtfJWz8r/XGiHgNQqiuJT3fMoQ2kVDrDMU1W4ffxleJGQbYDfhPOq1Pa
|
|
||||||
JGE/JhaDAxhRXUlPdmVkkzuYE6WVwJu6FvaBzi9DJ2CkUl1UYk6jXl8n0pFrplXc
|
|
||||||
AG9V+U0UmrLXc5ILN0Y6
|
|
||||||
=bWDk
|
|
||||||
-----END PGP SIGNATURE-----
|
|
||||||
125
content/blog/2023-07-15-prosody-traefik-2.md
Normal file
125
content/blog/2023-07-15-prosody-traefik-2.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<!-- title: Running Prosody on Port 443 Behind traefik 2: Electric ALPN -->
|
||||||
|
<!-- description: In this blog post, I tell you how I changed my setup for proxying my XMPP server using traefik -->
|
||||||
|
<!-- render: yes -->
|
||||||
|
Hello everyone. Long time, no read.
|
||||||
|
|
||||||
|
In 2020, I published a post titled "[Running Prosody on Port 443 Behind traefik](https://blog.polynom.me/Running-Prosody-traefik.html)", where I described how I run my XMPP server
|
||||||
|
behind the "application proxy" [*traefik*](https://github.com/traefik/traefik).
|
||||||
|
I did this because I wanted to run my XMPP server *prosody* on port 443, so that the clients connected
|
||||||
|
to my server can bypass firewalls that only allow web traffic. While that approach worked,
|
||||||
|
over the last three years I changed my setup dramatically.
|
||||||
|
|
||||||
|
While migrating my old server from *Debian* to *NixOS*, I decided that I wanted a website
|
||||||
|
hosted at the same domain I host my XMPP server at. This, however, was not possible with
|
||||||
|
*traefik* back then because it only allowed the `HostSNI` rule, which differentiates TLS
|
||||||
|
connections using the sent *Server Name Indication*. This is a problem, because a connection
|
||||||
|
to `polynom.me` the website and `polynom.me` the XMPP server both result in the same SNI being
|
||||||
|
sent by a connecting client.
|
||||||
|
|
||||||
|
Some time later, I stumbled upon [*sslh*](https://github.com/yrutschle/sslh), which is a
|
||||||
|
tool similar to *traefik* in that it allows hosting multiple services on the same port, all
|
||||||
|
differentiated by the SNI **and** the ALPN set by the connecting client. ALPN, or *Application-Layer Protocol Negotiation*, is an extension
|
||||||
|
to TLS which allows a connecting client to advertise the protocol(s) it would like to use
|
||||||
|
inside the encrypted session [(source)](https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation). As such, I put
|
||||||
|
*sslh* in front of my *traefik* and told it to route XMPP traffic (identified with an ALPN
|
||||||
|
of `xmpp-client`) to my prosody server and everything else to my *traefik* server. While this
|
||||||
|
worked well, there were two issues:
|
||||||
|
|
||||||
|
1. I was not running *sslh* in its ["transparent mode"](https://github.com/yrutschle/sslh/blob/master/doc/config.md#transparent-proxy-support), which uses some fancy iptable rules to allow the services behind it to see a connecting client's real IP address instead of just `127.0.0.1`. However, this requires more setup to work. This is an issue for services which enforce rate limits, like *NextCloud* and *Akkoma*. If one of theses services gets hit by many requests, all the services see are requests from `127.0.0.1` and may thus rate limit (or ban) `127.0.0.1`, meaning that all - even legitimate - requests are rate limited. Additionally, I was not sure if I could just use this to route an incoming IPv6 request to `127.0.0.1`, which is an IPv4 address.
|
||||||
|
2. One day, as I was updating my server, I noticed that all my web services were responding very slowly. After some looking around, it turned out that *sslh* took about 5 seconds to route IPv6 requests, but not IPv4 requests. As I did not change anything (besides update the server), to this day I am not sure what happened.
|
||||||
|
|
||||||
|
Due to these two issues, I decided to revisit the idea I described in my old post.
|
||||||
|
|
||||||
|
## The Prosody Setup
|
||||||
|
|
||||||
|
On the prosody-side of things, I did not change a lot compared to the old post. I did, however,
|
||||||
|
migrate from the `legacy_ssl_*` options to the newer `c2s_direct_tls_*` options, which
|
||||||
|
[replace the former](https://hg.prosody.im/trunk/file/tip/doc/doap.xml#l758).
|
||||||
|
|
||||||
|
Thus, my prosody configuration regarding direct TLS connections now looks like this:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
c2s_direct_tls_ports = { 5223 }
|
||||||
|
c2s_direct_tls_ssl = {
|
||||||
|
[5223] = {
|
||||||
|
key = "/etc/prosody/certs/polynom.me.key";
|
||||||
|
certificate = "/etc/prosody/certs/polynom.me.crt";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## The *Traefik* Setup
|
||||||
|
|
||||||
|
On *traefik*-side of things, only one thing really changed: Instead of just having a rule using
|
||||||
|
`HostSNI`, I now also require that the connection with the XMPP server advertises an ALPN
|
||||||
|
of `xmpp-client`, which is specified in the
|
||||||
|
[appropriate XMPP spec](https://xmpp.org/extensions/xep-0368.html). From my deployment
|
||||||
|
experience, all clients I tested (*Conversations*, *Blabber*, *Gajim*, *Dino*, *Monal*, [Moxxy](https://moxxy.org))
|
||||||
|
correctly set the ALPN when connecting via a direct TLS connection.
|
||||||
|
|
||||||
|
So my *traefik* configuration now looks something like this (Not really, because I let NixOS
|
||||||
|
generate the actual config, but it is very similar):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
tcp:
|
||||||
|
routers:
|
||||||
|
xmpps:
|
||||||
|
entrypoints:
|
||||||
|
- "https"
|
||||||
|
rule: "HostSNI(`polynom.me`) && ALPN(`xmpp-client`)"
|
||||||
|
service: prosody
|
||||||
|
tls:
|
||||||
|
passthrough: true
|
||||||
|
# [...]
|
||||||
|
services:
|
||||||
|
prosody:
|
||||||
|
loadBalancer:
|
||||||
|
servers:
|
||||||
|
- address: "127.0.0.1:5223"
|
||||||
|
|
||||||
|
http:
|
||||||
|
routers:
|
||||||
|
web-secure:
|
||||||
|
entrypoints:
|
||||||
|
- "https"
|
||||||
|
rule: "Host(`polynom.me`)"
|
||||||
|
service: webserver
|
||||||
|
tls:
|
||||||
|
```
|
||||||
|
|
||||||
|
The entrypoint `https` is just set to listen on `:443`. This way, I can route IPv4 and IPv6
|
||||||
|
requests. Also note the `passthrough: true` in the XMPP router's `tls` settings. If this is
|
||||||
|
not set to `true`, then *traefik* would terminate the connection's TLS session before passing
|
||||||
|
the data to the XMPP server.
|
||||||
|
|
||||||
|
However, this config has one really big issue: In order
|
||||||
|
to have the website hosted at `polynom.me` be served using TLS, I have to set the
|
||||||
|
router's `tls` attribute. The *traefik*
|
||||||
|
documentation says that "*If both HTTP routers and TCP routers listen to the
|
||||||
|
same entry points, the TCP routers will apply before the HTTP routers. If no matching route
|
||||||
|
is found for the TCP routers, then the HTTP routers will take over.*"
|
||||||
|
[(source)](https://doc.traefik.io/traefik/routing/routers/#general_1).
|
||||||
|
|
||||||
|
This, however, does not seem to be the case if a HTTP router (in my example with ```Host(`polynom.me`)```) and a TCP router (in my example with ```HostSNI(`polynom.me`)```) respond to the same
|
||||||
|
SNI **and** the HTTP router has its `tls` attribute set. In that case, the HTTP router appears
|
||||||
|
to be checked first and will complain, if the sent ALPN is not one of the
|
||||||
|
[HTTP ALPNs](https://developer.mozilla.org/en-US/docs/Glossary/ALPN), for example when
|
||||||
|
connecting using XMPP. As such we can connect to the HTTP server but not to the
|
||||||
|
XMPP server.
|
||||||
|
|
||||||
|
It appears to be an issue that [I am not alone with](https://github.com/traefik/traefik/issues/9922), but also
|
||||||
|
one that is not fixed. So I tried digging around in *traefik*'s code and tried a couple of
|
||||||
|
things. So for my setup to work, I have to apply [this patch](https://github.com/PapaTutuWawa/traefik/commit/36f0e3c805ca4e645f3313f667a6b3ff5e2fe4a9) to *traefik*. With that, the issue *appears*
|
||||||
|
to be gone, and I can access both my website and my XMPP server on the same domain and on the
|
||||||
|
same port. Do note that this patch is not upstreamed and may break things. For me, it
|
||||||
|
works. But I haven't run extensive tests or *traefik*'s integration and unit tests.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
This approach solves problem 2 fully and problem 1 partially. *Traefik* is able to route
|
||||||
|
the connections correctly with no delay, compared to *sslh*. It also provides my web services
|
||||||
|
with the connecting clients' IP addresses using HTTP headers. It does not, however, provide
|
||||||
|
my XMPP server with a connecting client's IP address. This could be solved with some clever
|
||||||
|
trickery, like telling *traefik* to use the [*PROXY* protocol](https://doc.traefik.io/traefik/routing/services/#proxy-protocol) when connecting to prosody,
|
||||||
|
and enabling the [`net_proxy`](https://modules.prosody.im/mod_net_proxy.html) module. However,
|
||||||
|
I have not yet tried such a setup, though I am very curious and may try that out.
|
||||||
102
content/blog/2023-07-24-Android-Yubikey-Signing.md
Normal file
102
content/blog/2023-07-24-Android-Yubikey-Signing.md
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
<!-- title: Signing Android Apps Using a YubiKey (on NixOS) -->
|
||||||
|
<!-- render: yes -->
|
||||||
|
In my spare time, I currently develop two Android apps using *Flutter*: [AniTrack](https://codeberg.org/PapaTutuWawa/anitrack), a
|
||||||
|
simple anime and manga tracker based on my own needs, and [Moxxy](https://moxxy.org), a modern XMPP
|
||||||
|
client. While I don't provide release builds for AniTrack, I do for Moxxy. Those
|
||||||
|
are signed using the key-pair that Flutter generates. I thought to myself: "Wouldn't it be cool if I could keep
|
||||||
|
the key-pair on a separate device which does the signing for me?". The consequence
|
||||||
|
of this thought is that I bought a *YubiKey 5c*. However, as always, using it for my
|
||||||
|
purposes did not go without issues.
|
||||||
|
|
||||||
|
The first issue is that the official [*Android* documentation](https://developer.android.com/build/building-cmdline#deploy_from_bundle)
|
||||||
|
says to use the `apksigner` tool for creating the signature. [The *YubiKey* documentation](https://developers.yubico.com/PIV/Guides/Android_code_signing.html), however,
|
||||||
|
uses `jarsigner`. While I, at first, did not think much of it, *Android* has
|
||||||
|
[different versions of the signature algorithm](https://source.android.com/docs/security/features/apksigning/): `v1` (what `jarsigner` does), `v2`, `v3`, `v3.1` and
|
||||||
|
`v4`. While it seems like it would be no problem to just use `v1` signatures, *Flutter*, by default,
|
||||||
|
generates `v1` and `v2` signatures, so I thought that I should keep it like that.
|
||||||
|
|
||||||
|
So, the solution is to just use `apksigner` instead of `jarsigner`, like [another person on the Internet](https://geoffreymetais.github.io/code/key-signing/) did.
|
||||||
|
But that did not work for me. Running `apksigner` like that makes it complain that `apksigner` cannot
|
||||||
|
access the required `sun.security.pkcs11.SunPKCS11` Java class.
|
||||||
|
|
||||||
|
```
|
||||||
|
> /nix/store/ib27l0593bi4ybff06ndhpb8gyhx5zfv-android-sdk-env/share/android-sdk/build-tools/34.0.0/apksigner sign \
|
||||||
|
--ks NONE \
|
||||||
|
--ks-pass "pass:<YubiKey PIN>" \
|
||||||
|
--provider-class sun.security.pkcs11.SunPKCS11 \
|
||||||
|
--provider-arg ./provider.cfg \
|
||||||
|
--ks-type PKCS11 \
|
||||||
|
--min-sdk-version 24 \
|
||||||
|
--max-sdk-version 34 \
|
||||||
|
--in unsigned.apk \
|
||||||
|
--out signed.apk
|
||||||
|
|
||||||
|
Exception in thread "main" java.lang.IllegalAccessException: class com.android.apksigner.ApkSignerTool$ProviderInstallSpec cannot access class sun.security.pkcs11.SunPKCS11 (in module jdk.crypto.cryptoki) because module jdk.crypto.cryptoki does not export sun.security.pkcs11 to unnamed module @75640fdb
|
||||||
|
at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:392)
|
||||||
|
at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:674)
|
||||||
|
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:489)
|
||||||
|
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
|
||||||
|
at com.android.apksigner.ApkSignerTool$ProviderInstallSpec.installProvider(ApkSignerTool.java:1233)
|
||||||
|
at com.android.apksigner.ApkSignerTool$ProviderInstallSpec.access$200(ApkSignerTool.java:1201)
|
||||||
|
at com.android.apksigner.ApkSignerTool.sign(ApkSignerTool.java:343)
|
||||||
|
at com.android.apksigner.ApkSignerTool.main(ApkSignerTool.java:92)
|
||||||
|
```
|
||||||
|
|
||||||
|
It may only be an issue because I use NixOS, as I
|
||||||
|
cannot find another instance of someone else having this issue. But I still want my APK signed using the key-pair
|
||||||
|
on my *YubiKey*. After a lot of trial and error, I found out that I can force Java to export certain classes
|
||||||
|
using the `--add-exports` flag. Since `apksigner` complained that the security classes are not exported to its
|
||||||
|
unnamed class, I had to specify `--add-exports sun.security.pkcs11.SunPKCS11=ALL-UNNAMED`.
|
||||||
|
|
||||||
|
## My Setup
|
||||||
|
|
||||||
|
TL;DR: I wrapped this entire setup (minus the Gradle config as that's a per-project thing) into a fancy [script](https://codeberg.org/PapaTutuWawa/bits-and-bytes/src/branch/master/src/flutter/build.sh).
|
||||||
|
|
||||||
|
My provider configuration for the signature is exactly like the one provided in [previously mentioned blog post](https://geoffreymetais.github.io/code/key-signing/#set-up-your-own-management-key),
|
||||||
|
with the difference that I cannot use the specified path to the `opensc-pkcs11.so` as I am on NixOS, where such
|
||||||
|
paths are not used. So in my setup, I either use the Nix REPL to build the derivation for `opensc` and then
|
||||||
|
use its `lib/opensc-pkcs11.so` path (`/nix/store/h2bn9iz4zqzmkmmjw9b43v30vhgillw4-opensc-0.22.0` in this case) for testing or, as
|
||||||
|
used in [AniTrack](https://codeberg.org/PapaTutuWawa/anitrack/src/branch/master/flake.nix), let Nix figure out the path by building
|
||||||
|
the config file from within my Nix Flake:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
# ...
|
||||||
|
providerArg = pkgs.writeText "provider-arg.cfg" ''
|
||||||
|
name = OpenSC-PKCS11
|
||||||
|
description = SunPKCS11 via OpenSC
|
||||||
|
library = ${pkgs.opensc}/lib/opensc-pkcs11.so
|
||||||
|
slotListIndex = 0
|
||||||
|
'';
|
||||||
|
# ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Next, to force Java to export the `sun.security.pkcs11.SunPKCS11` class to `apksigner`'s unnamed class, I added `--add-exports sun.security.pkcs11.SunPKCS11`
|
||||||
|
to the Java command line. There are two ways of doing this:
|
||||||
|
|
||||||
|
1. Since `apksigner` is just a wrapper script around calling `apksigner.jar`, we could patch the wrapper script to include this parameter.
|
||||||
|
2. Use the wrapper script's built-in mechanism to pass arguments to the `java` command.
|
||||||
|
|
||||||
|
While option 1 would work, it would require, in my case, to override the derivation that builds my Android SDK environment, which I am not that fond of.
|
||||||
|
Using `apksigner`'s way of specifying Java arguments (`-J`) is much easier. However, there is a little trick to it: When you pass `-Jsomething` to `apksigner`,
|
||||||
|
the wrapper scripts transforms it to `java -something`. As such, we cannot pass `-Jadd-exports sun.security.pkcs11.SunPKCS11` because it would get transformed
|
||||||
|
to `java -add-exports sun.security.[...]`, which is not what we want. To work around this, I quote the entire parameter to trick Bash into thinking that I'm
|
||||||
|
passing a single argument: `-J"-add-exports sun.security.pkcs11.SunPKCS11"`. This makes the wrapper append `--add-exports sun.security.pkcs11.SunPKCS11` to the
|
||||||
|
Java command line, ultimately allowing me to sign unsigned Android APKs with the key-pair on my *YubiKey*.
|
||||||
|
|
||||||
|
Since signing a signed APK makes little sense, we also need to tell Gradle to *not* sign the APK. In the case of Flutter apps, I modified the `android/app/build.gradle`
|
||||||
|
file to use a null signing config:
|
||||||
|
|
||||||
|
```gradle
|
||||||
|
android {
|
||||||
|
// ...
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
// This prevents Gradle from signing release builds.
|
||||||
|
// I don't care what happens to debug builds as I'm not distributing them.
|
||||||
|
signingConfig null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
8
flake.lock
generated
8
flake.lock
generated
@@ -36,16 +36,16 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs_2": {
|
"nixpkgs_2": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1638239011,
|
"lastModified": 1689449371,
|
||||||
"narHash": "sha256-AjhmbT4UBlJWqxY0ea8a6GU2C2HdKUREkG43oRr3TZg=",
|
"narHash": "sha256-sK3Oi8uEFrFPL83wKPV6w0+96NrmwqIpw9YFffMifVg=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "a7ecde854aee5c4c7cd6177f54a99d2c1ff28a31",
|
"rev": "29bcead8405cfe4c00085843eb372cc43837bb9d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "21.11",
|
"ref": "nixpkgs-unstable",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
|||||||
10
flake.nix
10
flake.nix
@@ -2,7 +2,7 @@
|
|||||||
description = "The blog hosted at https://blog.polynom.me";
|
description = "The blog hosted at https://blog.polynom.me";
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/21.11";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
assets.url = "git+https://git.polynom.me/polynom.me/shared-assets.git";
|
assets.url = "git+https://git.polynom.me/polynom.me/shared-assets.git";
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -16,9 +16,17 @@
|
|||||||
in {
|
in {
|
||||||
packages = forAllSystems (system: let
|
packages = forAllSystems (system: let
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
|
||||||
|
tailwindWithTypography = pkgs.nodePackages.tailwindcss.overrideAttrs (old: {
|
||||||
|
plugins = [
|
||||||
|
pkgs.nodePackages."@tailwindcss/typography"
|
||||||
|
];
|
||||||
|
});
|
||||||
in {
|
in {
|
||||||
default = pkgs.callPackage ./pkgs/blog.nix {
|
default = pkgs.callPackage ./pkgs/blog.nix {
|
||||||
shared-assets = assets.packages.${system}.default;
|
shared-assets = assets.packages.${system}.default;
|
||||||
|
|
||||||
|
inherit tailwindWithTypography;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
28
input.css
Normal file
28
input.css
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
article > p > a, h1, h2, h3, h4, h5, h6 {
|
||||||
|
@apply text-indigo-400 !important;
|
||||||
|
}
|
||||||
|
article > p > strong, code {
|
||||||
|
@apply text-white !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
article > h1, h2, h3, h4, h5, h6 {
|
||||||
|
@apply text-indigo-400 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: #212121;
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
@apply text-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
@apply text-indigo-400 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,10 @@
|
|||||||
<div class="horizontal-center">
|
<!-- Post item -->
|
||||||
<div class="post-list-item">
|
<div class="flex flex-col pt-4">
|
||||||
<h2><a class="post-list-item-title" href="/{{ slug }}.html">{{ title }}</a></h2>
|
<a href="/{{ slug }}.html"><h1 class="text-indigo-400 prose prose-lg text-xl">{{ title }}</h1></a>
|
||||||
|
<span class="text-md mt-2">Posted on {{ date }}</span>
|
||||||
|
|
||||||
<p><b>> {{ date }}</b></p>
|
<!-- Blurp -->
|
||||||
|
<span class="prose text-white mt-4">
|
||||||
<p class="post-summary">
|
{{ summary }}
|
||||||
<div class="quote text">
|
</span>
|
||||||
{{ summary }}...
|
|
||||||
</div>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
<div class="post-list">
|
<!-- Container for posts -->
|
||||||
<div class="vertical">
|
<div class="mx-auto">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,50 +1,43 @@
|
|||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>{{ title }}</title>
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link href="/assets/css/index.css" rel="stylesheet" />
|
||||||
|
<link href="/assets/css/code.css" rel="stylesheet" />
|
||||||
|
<link href="/feed.xml" type="application/atom+xml" rel="alternate" title="Moxxy Blog" />
|
||||||
|
|
||||||
<meta property="og:title" content="{{ title }}" />
|
<meta property="og:title" content="{{ title }}" />
|
||||||
<meta property="og:description" content="{{ description }}" />
|
<meta property="og:description" content="{{ description }}" />
|
||||||
|
|
||||||
<meta charset="UTF-8" />
|
<!-- Blog -->
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
|
<link rel="alternative"
|
||||||
<link rel="stylesheet" href="{{ page_assets }}/css/main.css" />
|
type="application/rss+xml"
|
||||||
<link rel="stylesheet" href="/assets/css/blog.css" />
|
title="PapaTutuWawa's Blog"
|
||||||
<link rel="stylesheet" href="/assets/css/syntax.css" />
|
href="https://{{ blog_url }}/atom.xml" />
|
||||||
<link rel="me" href="https://fosstodon.org/@polynomdivision" />
|
|
||||||
|
<!-- Optional MathJax -->
|
||||||
{{ mathjax_include }}
|
{{ mathjax_include }}
|
||||||
|
|
||||||
|
<title>{{ title }}</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="horizontal-center">
|
<div class="flex flex-col p-2 md:p-8 items-start md:w-4/5 mx-auto">
|
||||||
<div class="vertical header">
|
<!-- Header -->
|
||||||
<div id="header" class="horizontal">
|
<div class="flex flex-row self-center">
|
||||||
<img class="avatar" src="{{ page_assets }}/img/avatar.jpg" />
|
<img class="w-12 h-12 md:w-24 md:h-24 rounded-lg" src="{{ page_assets }}/img/avatar.jpg" alt="Profile picture"/>
|
||||||
|
<div class="ml-4 self-center">
|
||||||
|
<a class="self-center text-2xl font-bold" href="/">PapaTutuWawa's Blog</a>
|
||||||
|
|
||||||
<div class="vertical-center">
|
<ul class="list-none">
|
||||||
<span class="name-title">PapaTutuWawa's Blog</span>
|
<li class="inline mr-8"><a href="/index.html">Posts</a></li>
|
||||||
|
<li class="inline mr-8"><a href="/atom.xml">RSS</a></li>
|
||||||
<div id="header-links">
|
<li class="inline mr-8"><a href="https://polynom.me">About</a></li>
|
||||||
<ul>
|
|
||||||
<li><a href="index.html">Posts</a></li>
|
|
||||||
<li><a href="/atom.xml">RSS</a></li>
|
|
||||||
<li><a href="https://polynom.me">About</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="horizontal-center">
|
|
||||||
{{ content }}
|
{{ content }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
<center class="footer">
|
|
||||||
Created by <i>PapaTutuWawa</i> with <3 using
|
|
||||||
<a href="https://github.com/google/roboto">Roboto</a>,
|
|
||||||
<a href="https://github.com/RedHatOfficial/Overpass">Overpass</a> and
|
|
||||||
<a href="https://github.com/sunainapai/makesite">makesite</a>
|
|
||||||
</center>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,24 +1,19 @@
|
|||||||
<div class="horizontal-center stretch-horizontally">
|
<!-- Container for posts -->
|
||||||
<div class="post">
|
<div class="mx-auto mt-4 w-full md:max-w-prose">
|
||||||
<article>
|
<h1 class="text-indigo-400 text-3xl">{{ title }}</h1>
|
||||||
<h1>{{ title }}</h1>
|
|
||||||
|
|
||||||
<p>// Posted {{ date }}</p>
|
<span class="text-md mt-2">Posted on {{ date }}</span>
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://{{ git_url }}/PapaTutuWawa/blog.polynom.me/src/branch/master/content/blog/{{ file_name }}">Post source</a></li>
|
|
||||||
<li><a href="https://{{ git_url }}/PapaTutuWawa/blog.polynom.me/raw/branch/master/content/blog/{{ file_name }}.sig">Signed</a> with <a href="https://{{ email_gpg_url }}">this publickey</a></li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{ mathjax_warning }}
|
|
||||||
|
|
||||||
|
<!-- Actual article -->
|
||||||
|
<article class="prose lg:prose-lg text-white mt-4">
|
||||||
{{ content }}
|
{{ content }}
|
||||||
|
|
||||||
<br />
|
|
||||||
|
|
||||||
If you have any questions or comments, then feel free to send me an email
|
|
||||||
(Preferably with <a href="https://{{ email_gpg_url }}">GPG encryption</a>) to
|
|
||||||
{{ email_user }} [weird "a" with a circle] {{ email_domain }}.
|
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
|
<!-- Common post footer -->
|
||||||
|
<div class="mt-6">
|
||||||
|
<span class="prose lg:prose-lg text-md text-white">
|
||||||
|
If you have any questions or comments, then feel free to send me an email (Preferably with GPG encryption)
|
||||||
|
to {{ email_user }} [at] {{ email_domain }} or reach out to me on the Fediverse at <a href="https://{{ fediverse_url }}">{{ fediverse_handle }}</a>.
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"blog_description": "My personal blog. Mainly tech stuff.",
|
"blog_description": "My personal blog. Mainly tech stuff.",
|
||||||
"git_url": "git.polynom.me",
|
"git_url": "git.polynom.me",
|
||||||
"blog_url": "blog.polynom.me",
|
"blog_url": "blog.polynom.me",
|
||||||
"mastodon_url": "fosstodon.org/@polynomdivision",
|
"fediverse_url": "social.polynom.me/PapaTutuWawa",
|
||||||
|
"fediverse_handle": "@PapaTutuWawa@social.polynom.me",
|
||||||
"email_gpg_url": "pki.polynom.me/pubkeys/papatutuwawa.pub",
|
"email_gpg_url": "pki.polynom.me/pubkeys/papatutuwawa.pub",
|
||||||
"email_user": "papatutuwawa",
|
"email_user": "papatutuwawa",
|
||||||
"email_domain": "polynom.me",
|
"email_domain": "polynom.me",
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
{
|
{
|
||||||
lib, stdenv
|
lib, stdenv
|
||||||
, gnumake, imagemagick
|
, gnumake, imagemagick
|
||||||
, shared-assets
|
, python3
|
||||||
}:
|
, shared-assets # For makesite.py
|
||||||
stdenv.mkDerivation {
|
, tailwindWithTypography
|
||||||
|
}: let
|
||||||
|
pythonEnv = python3.withPackages (ps: with ps; [markdown pygments]);
|
||||||
|
in stdenv.mkDerivation {
|
||||||
pname = "blog";
|
pname = "blog";
|
||||||
version = "20211128";
|
version = "20230722";
|
||||||
|
|
||||||
src = ../.;
|
src = ../.;
|
||||||
|
|
||||||
buildInputs = [ shared-assets gnumake imagemagick ];
|
buildInputs = [ shared-assets gnumake imagemagick ];
|
||||||
|
|
||||||
patchPhase = ''
|
patchPhase = ''
|
||||||
sed -i Makefile -e "s|python ../shared-assets/makesite.py|python ${shared-assets}/bin/makesite.py|g"
|
sed -i Makefile -e "s|python ../shared-assets/makesite.py|${pythonEnv}/bin/python ${shared-assets}/bin/makesite.py|g"
|
||||||
sed -i Makefile -e "s|tar -czf blog.tar.gz _site||g"
|
sed -i Makefile -e "s|tar -czf blog.tar.gz _site||g"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
make buildnosign
|
make buildnosign
|
||||||
|
|
||||||
|
# Generate Tailwind CSS data
|
||||||
|
${tailwindWithTypography}/bin/tailwindcss --input ./input.css --output _site/assets/css/index.css
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
|
|||||||
10
tailwind.config.js
Normal file
10
tailwind.config.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
content: [
|
||||||
|
"./layout/*.html",
|
||||||
|
],
|
||||||
|
theme: {
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
require('@tailwindcss/typography'),
|
||||||
|
],
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user