Compare commits

...

No commits in common. "master" and "deploy" have entirely different histories.

51 changed files with 3706 additions and 834 deletions

2
.gitignore vendored
View file

@ -1,2 +0,0 @@
.statocles

View file

@ -0,0 +1,98 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>First Post - My Statocles Site</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">My Statocles Site</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<header>
<h1>First Post</h1>
<aside>
<time datetime="2017-09-25">
Posted on 2017-09-25
</time>
</aside>
<p class="tags">Tags:
</p>
</header>
<section id="section-1">
<h1>Welcome To Your Blog</h1>
<p>This is your first post. To edit this post, open up /blog/2017/09/25/first-post/index.markdown
in your text editor.</p>
<p><a href="http://preaction.me/statocles/pod/Statocles/Help/Content">Check the documentation for how to write Statocles
content</a></p>
</section>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<a class="button button-primary" href="/blog/2017/09/28/new-blog/index.html" rel="next">
Newer →
</a>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
</ul>
</nav>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -0,0 +1,106 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>new blog - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<header>
<h1>new blog</h1>
<aside>
<time datetime="2017-09-28">
Posted on 2017-09-28
</time>
</aside>
<p class="tags">Tags:
</p>
</header>
<section id="section-1">
<p>I&#39;m going to try to post here with real updates about both perlbot and App::EvalServerAdvanced.
I&#39;ll start posting updates and other interesting things I&#39;m planning to do with App::EvalServerAdvanced
to make get feedback on how to make both projects more useful to everyone. I&#39;m hoping I can turn App::EvalServerAdvanced
into a more generalized ephemeral container system, that lets you securely and quickly spin up a container containing user content
and perform an action on it.</p>
</section>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<a class="button button-primary" href="/blog/2017/10/02/new-old-perls/index.html" rel="next">
Newer →
</a>
</li>
</ul>
<h1>Comments</h1>
<section id="isso-thread"></section>
<noscript>Please enable JavaScript to view the comments. I promise it&#39;s not doing weird third party crap.</noscript>
<script data-isso="//isso.perlbot.pl/" data-isso-require-author="true" src="//isso.perlbot.pl/js/embed.min.js"></script>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -1,10 +1,9 @@
---
tags: ~
title: 'new blog'
title: New blog
---
I'm going to try to post here with real updates about both perlbot and App::EvalServerAdvanced.
I'll start posting updates and other interesting things I'm planning to do with App::EvalServerAdvanced
to make get feedback on how to make both projects more useful to everyone. I'm hoping I can turn App::EvalServerAdvanced
into a more generalized ephemeral container system, that lets you securely and quickly spin up a container containing user content
and perform an action on it.
I'm starting a new blog for keeping track of what I'm doing with perlbot and App::EvalServerAdvanced.
I'll also be posting ideas and other bits about what I'm planning on doing to try to get feedback from
everyone on the pastebin and on what features they might want from the evalserver to act as a more
general container driven setup to be useful.

View file

@ -0,0 +1,113 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>New old perls - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<header>
<h1>New old perls</h1>
<aside>
<time datetime="2017-10-02">
Posted on 2017-10-02
</time>
</aside>
<p class="tags">Tags:
</p>
</header>
<section id="section-1">
<p>So as part of my own insanity I&#39;ve managed to port/compile some old perl versions on linux and get the running in the eval sandbox.
Earlier today I completed this goal and there&#39;s now an available version of every major stable perl release: 1, 2, 3, 4, 5.000, 5.001, 5.002, 5.003, 5.004, 5.005, 5.6, 5.8, 5.10, 5.12, 5.14, 5.16, 5.18, 5.20, 5.22, 5.24, and 5.26.</p>
<p>Now that I&#39;ve completed this goal, I&#39;ve decided to bundle up all the seriously old perls into an
easy to download file for anyone else who has decided to go a little insane and try out some
ancient perl. You can find the file here, <a href="https://perlbot.pl/bstatic/newoldperls.tar.xz">https://perlbot.pl/bstatic/newoldperls.tar.xz</a>.
They&#39;re all expecting to live in /langs/ on a modernish linux system. That&#39;s actually a /langs
directory on the root filesystem. This was done to make getting them to work in the sandbox for the pastebin much easier.</p>
<p>Also available as a download in <a href="https://perlbot.pl/bstatic/newoldperls.tar.gz">.tar.gz</a> and <a href="https://perlbot.pl/bstatic/newoldperls.tar.zst">.tar.zst</a></p>
<p>ps. .tar.zst is compressed with zstandard/zstd, i wanted to try it out.</p>
</section>
<ul class="pager">
<li class="prev">
<a class="button button-primary" href="/blog/2017/09/28/new-blog/index.html" rel="prev">
← Older
</a>
</li>
<li class="next">
<a class="button button-primary" href="/blog/2017/10/23/seccomp-and-you/index.html" rel="next">
Newer →
</a>
</li>
</ul>
<h1>Comments</h1>
<section id="isso-thread"></section>
<noscript>Please enable JavaScript to view the comments. I promise it&#39;s not doing weird third party crap.</noscript>
<script data-isso="//isso.perlbot.pl/" data-isso-require-author="true" src="//isso.perlbot.pl/js/embed.min.js"></script>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -1,17 +0,0 @@
---
tags: ~
title: New old perls
---
So as part of my own insanity I've managed to port/compile some old perl versions on linux and get the running in the eval sandbox.
Earlier today I completed this goal and there's now an available version of every major stable perl release: 1, 2, 3, 4, 5.000, 5.001, 5.002, 5.003, 5.004, 5.005, 5.6, 5.8, 5.10, 5.12, 5.14, 5.16, 5.18, 5.20, 5.22, 5.24, and 5.26.
Now that I've completed this goal, I've decided to bundle up all the seriously old perls into an
easy to download file for anyone else who has decided to go a little insane and try out some
ancient perl. You can find the file here, [https://perlbot.pl/bstatic/newoldperls.tar.xz](https://perlbot.pl/bstatic/newoldperls.tar.xz).
They're all expecting to live in /langs/ on a modernish linux system. That's actually a /langs
directory on the root filesystem. This was done to make getting them to work in the sandbox for the pastebin much easier.
Also available as a download in [.tar.gz](https://perlbot.pl/bstatic/newoldperls.tar.gz) and [.tar.zst](https://perlbot.pl/bstatic/newoldperls.tar.zst)
ps. .tar.zst is compressed with zstandard/zstd, i wanted to try it out.

View file

@ -0,0 +1,184 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Seccomp and you - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<header>
<h1>Seccomp and you</h1>
<aside>
<time datetime="2017-10-10">
Posted on 2017-10-10
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<section id="section-1">
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<p>=== Handling flags to syscalls</p>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<p>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},</p>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</section>
<ul class="pager">
<li class="prev">
<a class="button button-primary" href="/blog/2017/10/02/new-old-perls/index.html" rel="prev">
← Older
</a>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -0,0 +1,193 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Seccomp and you - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<header>
<h1>Seccomp and you</h1>
<aside>
<time datetime="2017-10-23">
Posted on 2017-10-23
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<section id="section-1">
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</section>
<ul class="pager">
<li class="prev">
<a class="button button-primary" href="/blog/2017/10/02/new-old-perls/index.html" rel="prev">
← Older
</a>
</li>
<li class="next">
<a class="button button-primary" href="/blog/2018/03/16/seccomp-and-us/index.html" rel="next">
Newer →
</a>
</li>
</ul>
<h1>Comments</h1>
<section id="isso-thread"></section>
<noscript>Please enable JavaScript to view the comments. I promise it&#39;s not doing weird third party crap.</noscript>
<script data-isso="//isso.perlbot.pl/" data-isso-require-author="true" src="//isso.perlbot.pl/js/embed.min.js"></script>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -1,104 +0,0 @@
---
tags:
- evalserver
- seccomp
title: Seccomp and you
---
So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).
seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into 'profiles'. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.
I've created a few profiles to start with
- stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.
- file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it's a
tty. The flags that are allowed to go to a opening a file are defined in the "open_modes"
rules that will be covered later
- file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs
- file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls
- file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls
- file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.
- time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.
- ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
`CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID`
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.
- perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.
- exec_wrapper
This one is seriously special. It's not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can't inspect inside of pointers, there's no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn't perfectly secure since someone could overwrite the contents at a later point
but it's safe enough because an attacker can't view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.
There's also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).
Handling flags to syscalls
==========================
The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it's useful to be able to limit the flags they can
take.
{syscall => 'openat', permute_rules => [['2', '==', \'open_modes']]},
Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it's called 'open_modes'.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it'll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don't have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.
In the second part of this blog I'll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.

View file

@ -0,0 +1,159 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Seccomp and Us - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<header>
<h1>Seccomp and Us</h1>
<aside>
<time datetime="2018-03-16">
Posted on 2018-03-16
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/perlbot/" rel="tag">perlbot</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
<a href="/blog/tag/plugins/" rel="tag">plugins</a>
</p>
</header>
<section id="section-1">
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
</section>
<ul class="pager">
<li class="prev">
<a class="button button-primary" href="/blog/2017/10/23/seccomp-and-you/index.html" rel="prev">
← Older
</a>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
<h1>Comments</h1>
<section id="isso-thread"></section>
<noscript>Please enable JavaScript to view the comments. I promise it&#39;s not doing weird third party crap.</noscript>
<script data-isso="//isso.perlbot.pl/" data-isso-require-author="true" src="//isso.perlbot.pl/js/embed.min.js"></script>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

231
blog/index.atom Normal file
View file

@ -0,0 +1,231 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/</id>
<title>Perlbot.pl pastebin</title>
<updated>2018-03-16T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/index.atom" rel="self" />
<link href="https://perlbot.pl/blog/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</id>
<title>Seccomp and Us</title>
<link href="https://perlbot.pl/blog/2018/03/16/seccomp-and-us/" rel="alternate" />
<content type="html"><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></content>
<updated>2018-03-16T00:00:00Z</updated>
<category term="perlbot" />
<category term="seccomp" />
<category term="plugins" />
</entry>
<entry>
<id>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</id>
<title>Seccomp and you</title>
<link href="https://perlbot.pl/blog/2017/10/23/seccomp-and-you/" rel="alternate" />
<content type="html"><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></content>
<updated>2017-10-23T00:00:00Z</updated>
<category term="evalserver" />
<category term="seccomp" />
</entry>
<entry>
<id>https://perlbot.pl/blog/2017/10/02/new-old-perls/</id>
<title>New old perls</title>
<link href="https://perlbot.pl/blog/2017/10/02/new-old-perls/" rel="alternate" />
<content type="html"><![CDATA[
<p>So as part of my own insanity I&#39;ve managed to port/compile some old perl versions on linux and get the running in the eval sandbox.
Earlier today I completed this goal and there&#39;s now an available version of every major stable perl release: 1, 2, 3, 4, 5.000, 5.001, 5.002, 5.003, 5.004, 5.005, 5.6, 5.8, 5.10, 5.12, 5.14, 5.16, 5.18, 5.20, 5.22, 5.24, and 5.26.</p>
<p>Now that I&#39;ve completed this goal, I&#39;ve decided to bundle up all the seriously old perls into an
easy to download file for anyone else who has decided to go a little insane and try out some
ancient perl. You can find the file here, <a href="https://perlbot.pl/bstatic/newoldperls.tar.xz">https://perlbot.pl/bstatic/newoldperls.tar.xz</a>.
They&#39;re all expecting to live in /langs/ on a modernish linux system. That&#39;s actually a /langs
directory on the root filesystem. This was done to make getting them to work in the sandbox for the pastebin much easier.</p>
<p>Also available as a download in <a href="https://perlbot.pl/bstatic/newoldperls.tar.gz">.tar.gz</a> and <a href="https://perlbot.pl/bstatic/newoldperls.tar.zst">.tar.zst</a></p>
<p>ps. .tar.zst is compressed with zstandard/zstd, i wanted to try it out.</p>
]]></content>
<updated>2017-10-02T00:00:00Z</updated>
</entry>
<entry>
<id>https://perlbot.pl/blog/2017/09/28/new-blog/</id>
<title>new blog</title>
<link href="https://perlbot.pl/blog/2017/09/28/new-blog/" rel="alternate" />
<content type="html"><![CDATA[
<p>I&#39;m going to try to post here with real updates about both perlbot and App::EvalServerAdvanced.
I&#39;ll start posting updates and other interesting things I&#39;m planning to do with App::EvalServerAdvanced
to make get feedback on how to make both projects more useful to everyone. I&#39;m hoping I can turn App::EvalServerAdvanced
into a more generalized ephemeral container system, that lets you securely and quickly spin up a container containing user content
and perform an action on it.</p>
]]></content>
<updated>2017-09-28T00:00:00Z</updated>
</entry>
</feed>

339
blog/index.html Normal file
View file

@ -0,0 +1,339 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
<link href="/blog/index.atom" rel="alternate" type="application/atom+xml">
<link href="/blog/index.rss" rel="alternate" type="application/rss+xml">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<article>
<header>
<h1><a href="/blog/2018/03/16/seccomp-and-us/">Seccomp and Us</a></h1>
<aside>
<time datetime="2018-03-16">
Posted on 2018-03-16
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/perlbot/" rel="tag">perlbot</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
<a href="/blog/tag/plugins/" rel="tag">plugins</a>
</p>
</header>
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
</article>
<article>
<header>
<h1><a href="/blog/2017/10/23/seccomp-and-you/">Seccomp and you</a></h1>
<aside>
<time datetime="2017-10-23">
Posted on 2017-10-23
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</article>
<article>
<header>
<h1><a href="/blog/2017/10/02/new-old-perls/">New old perls</a></h1>
<aside>
<time datetime="2017-10-02">
Posted on 2017-10-02
</time>
</aside>
<p class="tags">Tags:
</p>
</header>
<p>So as part of my own insanity I&#39;ve managed to port/compile some old perl versions on linux and get the running in the eval sandbox.
Earlier today I completed this goal and there&#39;s now an available version of every major stable perl release: 1, 2, 3, 4, 5.000, 5.001, 5.002, 5.003, 5.004, 5.005, 5.6, 5.8, 5.10, 5.12, 5.14, 5.16, 5.18, 5.20, 5.22, 5.24, and 5.26.</p>
<p>Now that I&#39;ve completed this goal, I&#39;ve decided to bundle up all the seriously old perls into an
easy to download file for anyone else who has decided to go a little insane and try out some
ancient perl. You can find the file here, <a href="https://perlbot.pl/bstatic/newoldperls.tar.xz">https://perlbot.pl/bstatic/newoldperls.tar.xz</a>.
They&#39;re all expecting to live in /langs/ on a modernish linux system. That&#39;s actually a /langs
directory on the root filesystem. This was done to make getting them to work in the sandbox for the pastebin much easier.</p>
<p>Also available as a download in <a href="https://perlbot.pl/bstatic/newoldperls.tar.gz">.tar.gz</a> and <a href="https://perlbot.pl/bstatic/newoldperls.tar.zst">.tar.zst</a></p>
<p>ps. .tar.zst is compressed with zstandard/zstd, i wanted to try it out.</p>
</article>
<article>
<header>
<h1><a href="/blog/2017/09/28/new-blog/">new blog</a></h1>
<aside>
<time datetime="2017-09-28">
Posted on 2017-09-28
</time>
</aside>
<p class="tags">Tags:
</p>
</header>
<p>I&#39;m going to try to post here with real updates about both perlbot and App::EvalServerAdvanced.
I&#39;ll start posting updates and other interesting things I&#39;m planning to do with App::EvalServerAdvanced
to make get feedback on how to make both projects more useful to everyone. I&#39;m hoping I can turn App::EvalServerAdvanced
into a more generalized ephemeral container system, that lets you securely and quickly spin up a container containing user content
and perform an action on it.</p>
</article>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
<h1>Feeds</h1>
<ul class="list-inline">
<li>
<a href="/blog/index.atom" rel="alternate" type="application/atom+xml">
Atom
</a>
</li>
<li>
<a href="/blog/index.rss" rel="alternate" type="application/rss+xml">
RSS
</a>
</li>
</ul>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

234
blog/index.rss Normal file
View file

@ -0,0 +1,234 @@
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Perlbot.pl pastebin</title>
<link>https://perlbot.pl/blog/</link>
<atom:link href="https://perlbot.pl/blog/index.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and Us</title>
<link>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</link>
<guid>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</guid>
<description><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></description>
<pubDate>
Fri, 16 Mar 2018 00:00:00 +0000
</pubDate>
</item>
<item>
<title>Seccomp and you</title>
<link>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</link>
<guid>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</guid>
<description><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></description>
<pubDate>
Mon, 23 Oct 2017 00:00:00 +0000
</pubDate>
</item>
<item>
<title>New old perls</title>
<link>https://perlbot.pl/blog/2017/10/02/new-old-perls/</link>
<guid>https://perlbot.pl/blog/2017/10/02/new-old-perls/</guid>
<description><![CDATA[
<p>So as part of my own insanity I&#39;ve managed to port/compile some old perl versions on linux and get the running in the eval sandbox.
Earlier today I completed this goal and there&#39;s now an available version of every major stable perl release: 1, 2, 3, 4, 5.000, 5.001, 5.002, 5.003, 5.004, 5.005, 5.6, 5.8, 5.10, 5.12, 5.14, 5.16, 5.18, 5.20, 5.22, 5.24, and 5.26.</p>
<p>Now that I&#39;ve completed this goal, I&#39;ve decided to bundle up all the seriously old perls into an
easy to download file for anyone else who has decided to go a little insane and try out some
ancient perl. You can find the file here, <a href="https://perlbot.pl/bstatic/newoldperls.tar.xz">https://perlbot.pl/bstatic/newoldperls.tar.xz</a>.
They&#39;re all expecting to live in /langs/ on a modernish linux system. That&#39;s actually a /langs
directory on the root filesystem. This was done to make getting them to work in the sandbox for the pastebin much easier.</p>
<p>Also available as a download in <a href="https://perlbot.pl/bstatic/newoldperls.tar.gz">.tar.gz</a> and <a href="https://perlbot.pl/bstatic/newoldperls.tar.zst">.tar.zst</a></p>
<p>ps. .tar.zst is compressed with zstandard/zstd, i wanted to try it out.</p>
]]></description>
<pubDate>
Mon, 02 Oct 2017 00:00:00 +0000
</pubDate>
</item>
<item>
<title>new blog</title>
<link>https://perlbot.pl/blog/2017/09/28/new-blog/</link>
<guid>https://perlbot.pl/blog/2017/09/28/new-blog/</guid>
<description><![CDATA[
<p>I&#39;m going to try to post here with real updates about both perlbot and App::EvalServerAdvanced.
I&#39;ll start posting updates and other interesting things I&#39;m planning to do with App::EvalServerAdvanced
to make get feedback on how to make both projects more useful to everyone. I&#39;m hoping I can turn App::EvalServerAdvanced
into a more generalized ephemeral container system, that lets you securely and quickly spin up a container containing user content
and perform an action on it.</p>
]]></description>
<pubDate>
Thu, 28 Sep 2017 00:00:00 +0000
</pubDate>
</item>
</channel>
</rss>

118
blog/tag/evalserver.atom Normal file
View file

@ -0,0 +1,118 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/tag/evalserver/</id>
<title>Perlbot.pl pastebin</title>
<updated>2017-10-23T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/tag/evalserver.atom" rel="self" />
<link href="https://perlbot.pl/blog/tag/evalserver/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</id>
<title>Seccomp and you</title>
<link href="https://perlbot.pl/blog/2017/10/23/seccomp-and-you/" rel="alternate" />
<content type="html"><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></content>
<updated>2017-10-23T00:00:00Z</updated>
<category term="evalserver" />
<category term="seccomp" />
</entry>
</feed>

118
blog/tag/evalserver.rss Normal file
View file

@ -0,0 +1,118 @@
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Perlbot.pl pastebin</title>
<link>https://perlbot.pl/blog/tag/evalserver/</link>
<atom:link href="https://perlbot.pl/blog/tag/evalserver.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and you</title>
<link>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</link>
<guid>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</guid>
<description><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></description>
<pubDate>
Mon, 23 Oct 2017 00:00:00 +0000
</pubDate>
</item>
</channel>
</rss>

View file

@ -0,0 +1,207 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
<link href="/blog/tag/evalserver.atom" rel="alternate" type="application/atom+xml">
<link href="/blog/tag/evalserver.rss" rel="alternate" type="application/rss+xml">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<article>
<header>
<h1><a href="/blog/2017/10/23/seccomp-and-you/">Seccomp and you</a></h1>
<aside>
<time datetime="2017-10-23">
Posted on 2017-10-23
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</article>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
<h1>Feeds</h1>
<ul class="list-inline">
<li>
<a href="/blog/tag/evalserver.atom" rel="alternate" type="application/atom+xml">
Atom
</a>
</li>
<li>
<a href="/blog/tag/evalserver.rss" rel="alternate" type="application/rss+xml">
RSS
</a>
</li>
</ul>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

85
blog/tag/perlbot.atom Normal file
View file

@ -0,0 +1,85 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/tag/perlbot/</id>
<title>Perlbot.pl pastebin</title>
<updated>2018-03-16T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/tag/perlbot.atom" rel="self" />
<link href="https://perlbot.pl/blog/tag/perlbot/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</id>
<title>Seccomp and Us</title>
<link href="https://perlbot.pl/blog/2018/03/16/seccomp-and-us/" rel="alternate" />
<content type="html"><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></content>
<updated>2018-03-16T00:00:00Z</updated>
<category term="perlbot" />
<category term="seccomp" />
<category term="plugins" />
</entry>
</feed>

84
blog/tag/perlbot.rss Normal file
View file

@ -0,0 +1,84 @@
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Perlbot.pl pastebin</title>
<link>https://perlbot.pl/blog/tag/perlbot/</link>
<atom:link href="https://perlbot.pl/blog/tag/perlbot.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and Us</title>
<link>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</link>
<guid>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</guid>
<description><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></description>
<pubDate>
Fri, 16 Mar 2018 00:00:00 +0000
</pubDate>
</item>
</channel>
</rss>

173
blog/tag/perlbot/index.html Normal file
View file

@ -0,0 +1,173 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
<link href="/blog/tag/perlbot.atom" rel="alternate" type="application/atom+xml">
<link href="/blog/tag/perlbot.rss" rel="alternate" type="application/rss+xml">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<article>
<header>
<h1><a href="/blog/2018/03/16/seccomp-and-us/">Seccomp and Us</a></h1>
<aside>
<time datetime="2018-03-16">
Posted on 2018-03-16
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/perlbot/" rel="tag">perlbot</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
<a href="/blog/tag/plugins/" rel="tag">plugins</a>
</p>
</header>
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
</article>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
<h1>Feeds</h1>
<ul class="list-inline">
<li>
<a href="/blog/tag/perlbot.atom" rel="alternate" type="application/atom+xml">
Atom
</a>
</li>
<li>
<a href="/blog/tag/perlbot.rss" rel="alternate" type="application/rss+xml">
RSS
</a>
</li>
</ul>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

85
blog/tag/plugins.atom Normal file
View file

@ -0,0 +1,85 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/tag/plugins/</id>
<title>Perlbot.pl pastebin</title>
<updated>2018-03-16T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/tag/plugins.atom" rel="self" />
<link href="https://perlbot.pl/blog/tag/plugins/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</id>
<title>Seccomp and Us</title>
<link href="https://perlbot.pl/blog/2018/03/16/seccomp-and-us/" rel="alternate" />
<content type="html"><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></content>
<updated>2018-03-16T00:00:00Z</updated>
<category term="perlbot" />
<category term="seccomp" />
<category term="plugins" />
</entry>
</feed>

84
blog/tag/plugins.rss Normal file
View file

@ -0,0 +1,84 @@
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Perlbot.pl pastebin</title>
<link>https://perlbot.pl/blog/tag/plugins/</link>
<atom:link href="https://perlbot.pl/blog/tag/plugins.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and Us</title>
<link>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</link>
<guid>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</guid>
<description><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></description>
<pubDate>
Fri, 16 Mar 2018 00:00:00 +0000
</pubDate>
</item>
</channel>
</rss>

173
blog/tag/plugins/index.html Normal file
View file

@ -0,0 +1,173 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
<link href="/blog/tag/plugins.atom" rel="alternate" type="application/atom+xml">
<link href="/blog/tag/plugins.rss" rel="alternate" type="application/rss+xml">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<article>
<header>
<h1><a href="/blog/2018/03/16/seccomp-and-us/">Seccomp and Us</a></h1>
<aside>
<time datetime="2018-03-16">
Posted on 2018-03-16
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/perlbot/" rel="tag">perlbot</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
<a href="/blog/tag/plugins/" rel="tag">plugins</a>
</p>
</header>
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
</article>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
<h1>Feeds</h1>
<ul class="list-inline">
<li>
<a href="/blog/tag/plugins.atom" rel="alternate" type="application/atom+xml">
Atom
</a>
</li>
<li>
<a href="/blog/tag/plugins.rss" rel="alternate" type="application/rss+xml">
RSS
</a>
</li>
</ul>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

192
blog/tag/seccomp.atom Normal file
View file

@ -0,0 +1,192 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>https://perlbot.pl/blog/tag/seccomp/</id>
<title>Perlbot.pl pastebin</title>
<updated>2018-03-16T00:00:00Z</updated>
<link href="https://perlbot.pl/blog/tag/seccomp.atom" rel="self" />
<link href="https://perlbot.pl/blog/tag/seccomp/" rel="alternate" />
<generator version="0.086">Statocles</generator>
<entry>
<id>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</id>
<title>Seccomp and Us</title>
<link href="https://perlbot.pl/blog/2018/03/16/seccomp-and-us/" rel="alternate" />
<content type="html"><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></content>
<updated>2018-03-16T00:00:00Z</updated>
<category term="perlbot" />
<category term="seccomp" />
<category term="plugins" />
</entry>
<entry>
<id>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</id>
<title>Seccomp and you</title>
<link href="https://perlbot.pl/blog/2017/10/23/seccomp-and-you/" rel="alternate" />
<content type="html"><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></content>
<updated>2017-10-23T00:00:00Z</updated>
<category term="evalserver" />
<category term="seccomp" />
</entry>
</feed>

191
blog/tag/seccomp.rss Normal file
View file

@ -0,0 +1,191 @@
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Perlbot.pl pastebin</title>
<link>https://perlbot.pl/blog/tag/seccomp/</link>
<atom:link href="https://perlbot.pl/blog/tag/seccomp.rss" rel="self" type="application/rss+xml" />
<description>Blog feed of Perlbot.pl pastebin</description>
<generator>Statocles 0.086</generator>
<item>
<title>Seccomp and Us</title>
<link>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</link>
<guid>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</guid>
<description><![CDATA[
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/perlbot/">perlbot</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
<a href="https://perlbot.pl/blog/tag/plugins/">plugins</a>
</p>
]]></description>
<pubDate>
Fri, 16 Mar 2018 00:00:00 +0000
</pubDate>
</item>
<item>
<title>Seccomp and you</title>
<link>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</link>
<guid>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</guid>
<description><![CDATA[
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
<p>Tags:
<a href="https://perlbot.pl/blog/tag/evalserver/">evalserver</a>
<a href="https://perlbot.pl/blog/tag/seccomp/">seccomp</a>
</p>
]]></description>
<pubDate>
Mon, 23 Oct 2017 00:00:00 +0000
</pubDate>
</item>
</channel>
</rss>

284
blog/tag/seccomp/index.html Normal file
View file

@ -0,0 +1,284 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
<link href="/blog/tag/seccomp.atom" rel="alternate" type="application/atom+xml">
<link href="/blog/tag/seccomp.rss" rel="alternate" type="application/rss+xml">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<article>
<header>
<h1><a href="/blog/2018/03/16/seccomp-and-us/">Seccomp and Us</a></h1>
<aside>
<time datetime="2018-03-16">
Posted on 2018-03-16
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/perlbot/" rel="tag">perlbot</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
<a href="/blog/tag/plugins/" rel="tag">plugins</a>
</p>
</header>
<p>Back in october I wrote an article about how I was redesigning the seccomp system inside App::EvalServerAdvanced, a few months ago I finally finished that
and have gotten it ready to document it here. I ended up writing most of it as part of the module/project documentation and you can view it at https://metacpan.org/pod/App::EvalServerAdvanced::Seccomp so that it&#39;ll always be up to date.
What I didn&#39;t document there, were the plugins to enable more advanced behavior, since the API there hasn&#39;t fully been fleshed out, but I don&#39;t see them changing much in the future.</p>
<h2>Plugin Types</h2>
<h1>Constant Plugins</h1>
<p>These ones are pretty well defined and not likely to actually change. There&#39;s two provided by default, ::Seccomp::Plugin::Constant::POSIX and ::Seccomp::Plugin::Constant::LinuxClone
POSIX provides most of the constants from POSIX and some specific to the clone(2) syscall.</p>
<pre><code>constants:
plugins:
- &#39;POSIX&#39;
- &#39;LinuxClone&#39;
values:
TCGETS: 0x5401
FIOCLEX: 0x5451
FIONBIO: 0x5421
TIOCGPTN: 0x80045430
</code></pre>
<p>An example of the YAML above, that pulls in the two plugins, and here&#39;s how you use them:</p>
<pre><code> file_readonly:
include:
- file_open
permute:
open_modes:
- &#39;O_NONBLOCK&#39;
- &#39;O_EXCL&#39;
- &#39;O_RDONLY&#39;
- &#39;O_NOFOLLOW&#39;
- &#39;O_CLOEXEC&#39;
lang_ruby:
include:
- default
rules:
- syscall: clone
tests:
- [0, &#39;==&#39;, &#39;CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID&#39;]
- syscall: sigaltstack
</code></pre>
<p>So now the rules you write don&#39;t need to have strange magic numbers in them, like 0x80045430, or having to worry so much about portability among architectures.</p>
<h1>Rule generating plugins</h1>
<p>These are useful if you need to generate a rule a runtime, either because you need to look up some information that will change
or you otherwise need to know about what&#39;s being generated. The API for these plugins is very likely going to change, to add in
some more information that the plugins can use to make rules, things like the code and files being passed in, and other information
about the whole setup.</p>
<p>https://github.com/perlbot/App-EvalServerAdvanced/blob/master/lib/App/EvalServerAdvanced/Seccomp/Plugin/ExecWrapper.pm</p>
</article>
<article>
<header>
<h1><a href="/blog/2017/10/23/seccomp-and-you/">Seccomp and you</a></h1>
<aside>
<time datetime="2017-10-23">
Posted on 2017-10-23
</time>
</aside>
<p class="tags">Tags:
<a href="/blog/tag/evalserver/" rel="tag">evalserver</a>
<a href="/blog/tag/seccomp/" rel="tag">seccomp</a>
</p>
</header>
<p>So one of the big goals for App::EvalServerAdvanced is to make creating and maintaining a
sandbox for arbitrary code easier. The biggest way it does this is via Seccomp-bpf
(heretofore refered to as seccomp).</p>
<pre><code>seccomp-bpf is an extension to seccomp[8] that allows filtering of system calls using
a configurable policy implemented using Berkeley Packet Filter rules. It is used by
OpenSSH and vsftpd as well as the Google Chrome/Chromium web browsers on Chrome OS and
Linux. (In this regard seccomp-bpf achieves similar functionality to the older
systrace—which seems to be no longer supported for Linux).
-- https://en.wikipedia.org/wiki/Seccomp
</code></pre>
<p>Right now this is all handled in App::EvalServerAdvanced::Seccomp, with a large set of
predefined rules, organized into &#39;profiles&#39;. Each profile is intended to represent a
single kind of action that a program could do, such as open a file for reading, open a
file for writing, etc.</p>
<p>I&#39;ve created a few profiles to start with</p>
<ul>
<li><p>stdio
Allow reading from STDIN, and writing to STDOUT/STDERR.</p></li>
<li><p>file_open
Allows calling some file related system calls, such as: open, openat, close, select,
read (on any descriptor), pread64, lseek, fstat, lstat, stat, fcntl, and ioctl with flags to detect if it&#39;s a
tty. The flags that are allowed to go to a opening a file are defined in the &quot;open_modes&quot;
rules that will be covered later</p></li>
<li><p>file_opendir
Allows opening a directory to get a list of files, and also includes the file_open
profile to allow interacting with the handle. Essentially allows the behavior of /bin/ls
or similar programs</p></li>
<li><p>file_tty
Adds O_NOCTTY to the allowed flags passed to open() and similar calls</p></li>
<li><p>file_readonly
Adds O_NONBLOCK, O_EXCL, O_RDONLY, O_NOFOLLOW, O_CLOEXEC to be passed to open() and
similar calls</p></li>
<li><p>file_write
Adds O_CREAT, O_WRONLY, O_TRUNC, O_RDWR to be passed to open() and similar calls.
Also allows the use of write, pwrite64, mkdir, and chmod syscalls.</p></li>
<li><p>time_calls
Allows calling nanosleep, clock_gettime, and clock_getres syscalls. For perl this
means allowing time(), and similar calls, and sleep() along with Time::HiRes.</p></li>
<li><p>ruby_timer_thread
This one is a special ruby specific profile. It allows ruby to create a thread that
it uses internally, and only allows that thread creation with a specific set of flags,
<code>CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID</code>
This prevents it from doing arbitrary fork() calls, while still allowing the interpreter
to run. It also allows for pipe2 to be called to create communication between the two
threads.</p></li>
<li><p>perl_file_temp
This was added specifically for behavior of File::Temp, and might get folded into a
more generic profile. It allows chmod with a mode of 0600 and unlink to be called.</p></li>
<li><p>exec_wrapper
This one is seriously special. It&#39;s not a predefined set of rules, but in fact
generates the rules at runtime. This is because of limitations of seccomp. Since
seccomp can&#39;t inspect inside of pointers, there&#39;s no way to verify the contents of a
string being passed to execve(), instead we create a white-list of strings that can be
passed to it, and only allow calls to execve that are passed pointers to this syscall.
This isn&#39;t perfectly secure since someone could overwrite the contents at a later point
but it&#39;s safe enough because an attacker can&#39;t view the generated BPF to extract the
addresses, and the strings themselves should be gone from memory by the time their code
runs, preventing them from recreating the original addresses. This requires ASLR in order
to be effective at preventing an attacker from derriving the address of the strings from
previous runs.</p></li>
</ul>
<p>There&#39;s also some other profiles like ruby_timer_thread specifically for allowing node.js
to do similar things to ruby (create a thread, use epoll, etc.).</p>
<h1>Handling flags to syscalls</h1>
<p>The way the rules are defined allow syscalls like open() to not need special handling.
Since many syscalls can take flags, it&#39;s useful to be able to limit the flags they can
take.</p>
<pre><code>{syscall =&gt; &#39;openat&#39;, permute_rules =&gt; [[&#39;2&#39;, &#39;==&#39;, \&#39;open_modes&#39;]]},
</code></pre>
<p>Inside A::ESA::Seccomp you can define a syscall like the above, to take a set of
automatically generated rules from a permutation. In this cases it&#39;s called &#39;open_modes&#39;.
A profile can add (but not remove) values to the permutation rules, and then when the
whole BPF program gets compiled it&#39;ll generate all the applicable rules for you. This
makes setting up calls like open much much simpler since you don&#39;t have to write out all
possible modes yourself. This is also an area where I could be doing better to optimize
the whole thing, but have not done so yet. Seccomp itself supports doing some bitwise
operations that could make this more effective but they were not well exposed through
Linux::Seccomp when this was originally designed.</p>
<p>In the second part of this blog I&#39;ll document the proposed configuration
scheme using YAML 1.2 and the perl modules located in the sandbox root.</p>
</article>
<ul class="pager">
<li class="prev">
<button disabled>
← Older
</button>
</li>
<li class="next">
<button disabled>
Newer →
</button>
</li>
</ul>
</main>
</div>
<div class="three columns sidebar">
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
<li><a href="/blog/tag/evalserver/">evalserver</a></li>
<li><a href="/blog/tag/perlbot/">perlbot</a></li>
<li><a href="/blog/tag/plugins/">plugins</a></li>
<li><a href="/blog/tag/seccomp/">seccomp</a></li>
</ul>
</nav>
<h1>Feeds</h1>
<ul class="list-inline">
<li>
<a href="/blog/tag/seccomp.atom" rel="alternate" type="application/atom+xml">
Atom
</a>
</li>
<li>
<a href="/blog/tag/seccomp.rss" rel="alternate" type="application/rss+xml">
RSS
</a>
</li>
</ul>
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

62
index.html Normal file
View file

@ -0,0 +1,62 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Main Page - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<h1>Welcome To Your Site</h1>
<p>This is your first page. To edit this page, open up /index.markdown
in your text editor.</p>
<p><a href="http://preaction.me/statocles/pod/Statocles/Help/Content">Check the documentation for how to write Statocles
content</a></p>
</main>
</div>
<div class="three columns sidebar">
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -1,11 +0,0 @@
---
title: Main Page
---
# Welcome To Your Site
This is your first page. To edit this page, open up <%= $self->path %>
in your text editor.
[Check the documentation for how to write Statocles
content](http://preaction.me/statocles/pod/Statocles/Help/Content)

56
page/seccomp/index.html Normal file
View file

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>How seccomp works - Perlbot.pl pastebin</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">Perlbot.pl pastebin</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<p>... Content goes here ...</p>
</main>
</div>
<div class="three columns sidebar">
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

View file

@ -1,5 +0,0 @@
---
title: 'How seccomp works'
---
... Content goes here ...

56
page/test/index.html Normal file
View file

@ -0,0 +1,56 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1" name="viewport">
<link href="/theme/css/normalize.css" rel="stylesheet">
<link href="/theme/css/skeleton.css" rel="stylesheet">
<link href="/theme/css/statocles-default.css" rel="stylesheet">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<title>Testing page layout - My Statocles Site</title>
<meta content="Statocles 0.086" name="generator">
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/">My Statocles Site</a>
<ul>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<p>Markdown content goes here.</p>
</main>
</div>
<div class="three columns sidebar">
</div>
</div>
</div>
<footer>
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
</body>
</html>

5
robots.txt Normal file
View file

@ -0,0 +1,5 @@
Sitemap: https://perlbot.pl/sitemap.xml
User-Agent: *
Disallow:

149
site.yml
View file

@ -1,149 +0,0 @@
### Generated by Statocles version 0.086
# This is the site configuration file. The format is YAML, and the config is
# read by Beam::Wire, a dependency-injection library that builds complete
# objects. For full details on how to edit this file, see
# Statocles::Help::Config.
#
# This file contains configuration for objects. Each object has a name, like
# "site", "theme", or "blog_app". This name can be used to refer to the object
# later, for example, using "$ref: name".
#
# Every object has a "class". Developers can customize behavior by changing the
# class or creating their own classes. If you need help with an object, look at
# the class's documentation.
#
# Every object has "args", which are the object's attributes. See the class's
# documentation for a full list of attributes and what they do.
#
# Many objects have events. Event handlers can be configured using the "on"
# key. See the class's documentation for a list of possible events. Every
# event handler should have at least "$class" and a "$sub". "$class" is the
# plugin class. "$sub" is the plugin method to run. If necessary, you can
# add "$args" to configure the plugin object.
# site: This is the main site object. Site objects handle building and
# deploying, and store global site data like themes and navigation. See
# Statocles::Site for a full list of attributes and what they do.
site:
class: 'Statocles::Site'
args:
# title: This is the title of the site, shown in the <title> tag
title: 'Perlbot.pl pastebin'
# base_url: This is the base URL the site will be deployed to. It
# should be a full URL, and may contain a path, like:
#
# http://example.com/username
#
# If the base_url contains a path, all internal links will be
# rewritten appropriately.
base_url: 'https://perlbot.pl/'
# apps: These are the applications in this site. The name of the app,
# "blog", "page", or "static", is used to refer to it in commands.
apps:
# blog: This is the blog app
blog:
$ref: 'blog_app'
# page: This app turns any Markdown page into HTML
page:
$ref: 'page_app'
# static: This app does no processing at all. Good for images
static:
$ref: 'static_app'
# plugins: These are plugins that can add features and alter the
# content of the site.
plugins:
link_check:
$class: 'Statocles::Plugin::LinkCheck'
# theme: The theme builds and manages the templates. Use themes to
# change how your site looks.
theme:
$ref: 'theme'
# index: The path to the page that should be used for the site index.
index: '/page'
# nav: These are lists of navigation links used by the theme.
# Navigations are used to move between applications, or to go to
# specific, important pages.
#
# The "main" nav is the primary navigation for the site. Every theme
# should have this one.
#
# Each nav consists of an array of links. See the Statocles::Link class
# for a list of attributes and what they mean. The most important are
# "text", the text of the link, and "href", the URL to link to.
nav:
main:
- text: 'Blog'
href: '/blog'
# deploy: This is the deploy object, used to deploy this site.
deploy:
$ref: 'deploy'
isso:
enabled: true
# theme: These are the settings for the theme. See Statocles::Help::Theme for
# more information, and Statocles::Theme for a full list of attributes and what
# they do
theme:
class: 'Statocles::Theme'
args:
# store: The store points to the directory where the theme's
# templates are kept. Under-the-hood, this is a Statocles::Store
# object.
#
# Themes have a special syntax to refer to themes that come bundled with
# Statocles. See Statocles::Help::Theme for more information
store: 'theme'
# deploy: These are the settings for the site's deploy. See Statocles::Deploy::File
# for a full list of attributes and what they do.
deploy:
class: 'Statocles::Deploy::Git'
args:
branch: 'deploy'
#----------------------------------------------------------------------------
# Applications
#----------------------------------------------------------------------------
#
# All applications have a "url_root" attribute, which is the root URL of the
# app. All the app's pages will be under this URL.
#
# Most applications have a "store" attribute. The store points to the directory
# where the application's data is kept. Under-the-hood, this is a
# Statocles::Store object, but you only need to specify the directory path.
# blog_app: These are the settings for the blog application.
blog_app:
class: 'Statocles::App::Blog'
args:
url_root: '/blog'
store: 'blog'
# page_app: These are the settings for the page application.
page_app:
class: 'Statocles::App::Basic'
args:
store: 'page'
url_root: '/page'
# static_app: These are the settings for the static application.
static_app:
class: 'Statocles::App::Basic'
args:
store: 'static'
url_root: '/bstatic'

71
sitemap.xml Normal file
View file

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://perlbot.pl/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2018-03-19</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2018-03-16</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/2017/09/28/new-blog/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2017-09-28</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/2017/10/02/new-old-perls/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2017-10-02</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/2017/10/23/seccomp-and-you/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2017-10-23</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/2018/03/16/seccomp-and-us/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2018-03-16</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/tag/evalserver/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2017-10-23</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/tag/perlbot/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2018-03-16</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/tag/plugins/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2018-03-16</lastmod>
</url>
<url>
<loc>https://perlbot.pl/blog/tag/seccomp/</loc>
<changefreq>daily</changefreq>
<priority>0.3</priority>
<lastmod>2018-03-16</lastmod>
</url>
<url>
<loc>https://perlbot.pl/page/seccomp/</loc>
<changefreq>weekly</changefreq>
<priority>0.5</priority>
<lastmod>2018-03-19</lastmod>
</url>
</urlset>

View file

@ -1,57 +0,0 @@
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id><%= $site->url( $self->links( 'alternate' )->href ) %></id>
<title><%= $site->title %></title>
<updated><%= $self->date->strftime('%Y-%m-%dT%H:%M:%SZ') %></updated>
<link rel="self" href="<%= $site->url( $self->path ) %>"/>
<link rel="alternate" href="<%= $site->url( $self->links( 'alternate' )->href ) %>"/>
% if ( $page->author ) {
<author>
<name><%= $page->author->name %></name>
</author>
% }
<generator version="<%= $Statocles::VERSION %>">Statocles</generator>
% for my $p ( @$pages ) {
<entry>
<id><%= $site->url( $p->path ) %></id>
<title><%== $p->title %></title>
% if ( $p->author ) {
<author><name><%= $p->author %></name></author>
% }
<link rel="alternate" href="<%= $site->url( $p->path ) %>" />
<content type="html"><![CDATA[
% my @sections = $p->sections;
<%= $sections[0] %>
% if ( $p->links( 'crosspost' ) ) {
<ul>
% for my $link ( $p->links( 'crosspost' ) ) {
<li><a href="<%= $link->href %>">
Continue reading <em><%= $p->title %></em> on <%= $link->title %>...
</a></li>
% }
<li><a href="<%= $site->url( $p->path ) %>#section-2">
Continue reading on <%= $site->title %>
</a></li>
</ul>
% }
% elsif ( $p->sections > 1 ) {
<p><a href="<%= $site->url( $p->path ) %>#section-2">Continue reading...</a></p>
% }
% if ( $p->tags ) {
<p>Tags:
% for my $tag ( $p->tags ) {
<a href="<%= $site->url( $tag->href ) %>"><%== $tag->text %></a>
% }
</p>
% }
]]></content>
<updated><%= $p->date->strftime('%Y-%m-%dT%H:%M:%SZ') %></updated>
% for my $t ( $p->tags ) {
<category term="<%= $t->text %>" />
% }
</entry>
% }
</feed>

View file

@ -1,120 +0,0 @@
% if ( my $tag_text = $self->data->{ tag_text } ) {
<%= markdown $tag_text %>
% }
% for my $page ( @$pages ) {
<article>
<header>
<h1><a href="<%= $app->page_url( $page ) %>"><%== $page->title %></a></h1>
<aside>
<time datetime="<%= $page->date->strftime('%Y-%m-%d') %>">
Posted on <%= $page->date->strftime('%Y-%m-%d') %>
</time>
% if ( $page->author ) {
<span class="author">
by <%= $page->author %>
</span>
% }
% if ( $site->data->{disqus}{shortname} ) {
<a data-disqus-identifier="<%= $page->document->path %>" href="<%= $app->page_url( $page ) %>#disqus_thread">0 comments</a>
% }
</aside>
<p class="tags">Tags:
% for my $tag ( $page->tags ) {
<a href="<%= $tag->href %>" rel="tag"><%== $tag->text %></a>
% }
</p>
% if ( $page->links( 'crosspost' ) ) {
<p>Originally posted as:
% for my $link ( $page->links( 'crosspost' ) ) {
<a href="<%= $link->href %>">
<em><%= $page->title %></em> on <%= $link->title %>.
</a>
% }
</p>
% }
</header>
% my @sections = $page->sections;
<%= $sections[0] %>
% if ( @sections > 1 ) {
<p><a href="<%= $app->page_url( $page ) %>#section-2">Continue reading <%= $page->title %>...</a></p>
% }
</article>
% }
<ul class="pager">
<li class="prev">
% if ( $self->next ) {
<a class="button button-primary" rel="prev"
href="<%= $self->next %>"
>
&larr; Older
</a>
% }
% else {
<button disabled>
&larr; Older
</button>
% }
</li>
<li class="next">
% if ( $self->prev ) {
<a class="button button-primary" rel="next"
href="<%= $self->prev %>"
>
Newer &rarr;
</a>
% }
% else {
<button disabled>
Newer &rarr;
</button>
% }
</li>
</ul>
% if ( $site->data->{disqus}{shortname} ) {
<script type="text/javascript">
var disqus_shortname = '<%= $site->data->{disqus}{shortname} %>';
(function () {
var s = document.createElement('script'); s.async = true;
s.type = 'text/javascript';
s.src = '//' + disqus_shortname + '.disqus.com/count.js';
(document.getElementsByTagName('HEAD')[0] || document.getElementsByTagName('BODY')[0]).appendChild(s);
}());
</script>
% }
% content tags => begin
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
% for my $tag ( $app->tags ) {
<li><a href="<%= $tag->href %>"><%== $tag->text %></a></li>
% }
</ul>
</nav>
% end
% if ( my @links = $self->links( 'feed' ) ) {
% content feeds => begin
<h1>Feeds</h1>
<ul class="list-inline">
% for my $link ( @links ) {
<li>
<a href="<%= $link->href %>" rel="alternate" type="<%= $link->type %>">
<%= $link->text %>
</a>
</li>
% }
</ul>
% end
% }

View file

@ -1,54 +0,0 @@
%# RSS requires date/time in the 'C' locale as per RFC822. strftime() is one of
%# the few things that actually cares about locale.
% use POSIX qw( locale_h );
% my $current_locale = setlocale( LC_TIME );
% setlocale( LC_TIME, 'C' );
<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title><%= $site->title %></title>
<link><%= $site->url( $self->links( 'alternate' )->href ) %></link>
<atom:link href="<%= $site->url( $self->path ) %>" rel="self" type="application/rss+xml" />
<description>Blog feed of <%= $site->title %></description>
<generator>Statocles <%= $Statocles::VERSION %></generator>
% for my $p ( @$pages ) {
<item>
<title><%== $p->title %></title>
<link><%= $site->url( $p->path ) %></link>
<guid><%= $site->url( $p->path ) %></guid>
<description><![CDATA[
% my @sections = $p->sections;
<%= $sections[0] %>
% if ( $p->links( 'crosspost' ) ) {
<ul>
% for my $link ( $p->links( 'crosspost' ) ) {
<li><a href="<%= $link->href %>">
Continue reading <em><%= $p->title %></em> on <%= $link->title %>...
</a></li>
% }
<li><a href="<%= $site->url( $p->path ) %>#section-2">
Continue reading on <%= $site->title %>
</a></li>
</ul>
% }
% elsif ( $p->sections > 1 ) {
<p><a href="<%= $site->url( $p->path ) %>#section-2">Continue reading...</a></p>
% }
% if ( $p->tags ) {
<p>Tags:
% for my $tag ( $p->tags ) {
<a href="<%= $site->url( $tag->href ) %>"><%== $tag->text %></a>
% }
</p>
% }
]]></description>
<pubDate>
<%= $p->date->strftime('%a, %d %b %Y %H:%M:%S ') . sprintf q{%+05d}, $p->date->offset / 3600 %>
</pubDate>
</item>
% }
</channel>
</rss>
% setlocale( LC_TIME, $current_locale );

View file

@ -1,103 +0,0 @@
<header>
<h1><%== $self->title %></h1>
<aside>
<time datetime="<%= $self->date->strftime('%Y-%m-%d') %>">
Posted on <%= $self->date->strftime('%Y-%m-%d') %>
</time>
% if ( $self->author ) {
<span class="author">
by <%= $self->author %>
</span>
% }
</aside>
<p class="tags">Tags:
% for my $tag ( $self->tags ) {
<a href="<%= $tag->href %>" rel="tag"><%== $tag->text %></a>
% }
</p>
% if ( $self->links( 'crosspost' ) ) {
<p>Originally posted as:
% for my $link ( $self->links( 'crosspost' ) ) {
<a href="<%= $link->href %>">
<em><%= $self->title %></em> on <%= $link->title %>.
</a>
% }
</p>
% }
</header>
% my @sections = $self->sections;
% for my $i ( 0..$#sections ) {
<section id="section-<%= $i+1 %>">
<%= $sections[$i] %>
</section>
% }
<ul class="pager">
<li class="prev">
% if ( $self->next ) {
<a class="button button-primary" rel="prev"
href="<%= $self->next %>"
>
&larr; Older
</a>
% }
% else {
<button disabled>
&larr; Older
</button>
% }
</li>
<li class="next">
% if ( $self->prev ) {
<a class="button button-primary" rel="next"
href="<%= $self->prev %>"
>
Newer &rarr;
</a>
% }
% else {
<button disabled>
Newer &rarr;
</button>
% }
</li>
</ul>
% if ( $site->data->{disqus}{shortname} ) {
<h1>Comments</h1>
<div id="disqus_thread"></div>
<script type="text/javascript">
var disqus_shortname = '<%= $site->data->{disqus}{shortname} %>';
var disqus_identifier = '<%= $self->document->path %>';
var disqus_url = '<%= $site->url( $self->path ) %>';
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>
% }
<h1>Comments</h1>
<section id="isso-thread"></section>
<noscript>Please enable JavaScript to view the comments. I promise it's not doing weird third party crap.</noscript>
<script data-isso="//isso.perlbot.pl/"
data-isso-require-author="true"
src="//isso.perlbot.pl/js/embed.min.js"></script>
% content tags => begin
<nav id="tags">
<h1>Tags</h1>
<ul class="list-inline">
% for my $tag ( $app->tags ) {
<li><a href="<%= $tag->href %>"><%== $tag->text %></a></li>
% }
</ul>
</nav>
% end

View file

@ -1,89 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="/theme/css/normalize.css" />
<link rel="stylesheet" href="/theme/css/skeleton.css" />
<link rel="stylesheet" href="/theme/css/statocles-default.css" />
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<title><%== $self->title ? $self->title . ' - ' : '' %><%== $site->title %></title>
% if ( my $author = $self->author ) {
<meta name="author" content="<%== $author->name %>">
% }
<meta name="generator" content="Statocles <%= $Statocles::VERSION %>" />
% for my $link ( $self->links( 'feed' ) ) {
<link rel="alternate" href="<%= $link->href %>" type="<%= $link->type %>" />
% }
% if ( my $img = $site->images->{ 'icon' } ) {
<link rel="shortcut icon" href="<%= $img->src %>" />
% }
%= include 'site/head_after.html.ep'
% for my $link ( $site->links( 'stylesheet' ) ) {
<link rel="stylesheet" href="<%= $link->href %>" type="<%= $link->type || 'text/css' %>" />
% }
% for my $link ( $self->links( 'stylesheet' ) ) {
<link rel="stylesheet" href="<%= $link->href %>" type="<%= $link->type || 'text/css' %>" />
% }
% for my $link ( $site->links( 'script' ) ) {
<script src="<%= $link->href %>"></script>
% }
% for my $link ( $self->links( 'script' ) ) {
<script src="<%= $link->href %>"></script>
% }
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/"><%= $site->title %></a>
% if ( my @nav_links = $site->nav( 'main' ) ) {
<ul>
% for my $nav ( @nav_links ) {
<li>
<a href="<%= $nav->href %>"><%= $nav->text %></a>
</li>
% }
</ul>
% }
%= include 'site/navbar_extra.html.ep'
</div>
</nav>
%= include 'site/header_after.html.ep'
</header>
<div class="main container">
<div class="row">
<div class="nine columns">
<main>
<%= content %>
</main>
</div>
<div class="three columns sidebar">
%= include 'site/sidebar_before.html.ep';
%= content 'tags';
%= content 'feeds';
</div>
</div>
</div>
<footer>
%= include 'site/footer.html.ep'
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br/>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
% if ( $site->data->{google_analytics_id} ) {
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '<%= $site->data->{google_analytics_id} %>', 'auto');
ga('send', 'pageview');
</script>
% }
</body>
</html>

View file

@ -1,82 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="/theme/css/normalize.css" />
<link rel="stylesheet" href="/theme/css/skeleton.css" />
<link rel="stylesheet" href="/theme/css/statocles-default.css" />
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<title><%== $self->title ? $self->title . ' - ' : '' %><%== $site->title %></title>
% if ( my $author = $self->author ) {
<meta name="author" content="<%== $author->name %>">
% }
<meta name="generator" content="Statocles <%= $Statocles::VERSION %>" />
% for my $link ( $self->links( 'feed' ) ) {
<link rel="alternate" href="<%= $link->href %>" type="<%= $link->type %>" />
% }
% if ( my $img = $site->images->{ 'icon' } ) {
<link rel="shortcut icon" href="<%= $img->src %>" />
% }
%= include 'site/head_after.html.ep'
% for my $link ( $site->links( 'stylesheet' ) ) {
<link rel="stylesheet" href="<%= $link->href %>" type="<%= $link->type || 'text/css' %>" />
% }
% for my $link ( $self->links( 'stylesheet' ) ) {
<link rel="stylesheet" href="<%= $link->href %>" type="<%= $link->type || 'text/css' %>" />
% }
% for my $link ( $site->links( 'script' ) ) {
<script src="<%= $link->href %>"></script>
% }
% for my $link ( $self->links( 'script' ) ) {
<script src="<%= $link->href %>"></script>
% }
</head>
<body>
<header>
<nav class="navbar">
<div class="container">
<a class="brand" href="/"><%= $site->title %></a>
% if ( my @nav_links = $site->nav( 'main' ) ) {
<ul>
% for my $nav ( @nav_links ) {
<li>
<a href="<%= $nav->href %>"><%= $nav->text %></a>
</li>
% }
</ul>
% }
%= include 'site/navbar_extra.html.ep'
</div>
</nav>
%= include 'site/header_after.html.ep'
</header>
<div class="main container">
<div class="row">
<div class="twelve columns">
<main>
<%= content %>
</main>
</div>
</div>
</div>
<footer>
%= include 'site/footer.html.ep'
<div class="container tagline">
<a href="http://preaction.me/statocles">Made with Statocles</a><br/>
<a href="http://www.perl.org">Powered by Perl</a>
</div>
</footer>
% if ( $site->data->{google_analytics_id} ) {
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', '<%= $site->data->{google_analytics_id} %>', 'auto');
ga('send', 'pageview');
</script>
% }
</body>
</html>

View file

@ -1,16 +0,0 @@
<div class="crumbtrail">
<ul>
% for my $trail ( @{ $self->data->{ crumbtrail } } ) {
<li>
% if ( $trail->{href} ) {
<a href="<%= $trail->{href} %>"><%= $trail->{text} %></a>
% }
% else {
<%= $trail->{text} %>
% }
</li>
% }
</ul>
(<a href="<%= $self->data->{ source_path } %>">source</a>)
</div>
<%= $content %>

View file

@ -1,4 +0,0 @@
<a class="button" href="<%= $self->data->{ doc_path } %>">
Back to documentation
</a>
<pre><%== $content %></pre>

View file

@ -1,4 +0,0 @@
Sitemap: <%= $site->url( 'sitemap.xml' ) %>
User-Agent: *
Disallow:

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
% for my $page ( @$pages ) {
<url>
<loc><%= $site->url( $page->path ) %></loc>
<changefreq><%= $page->search_change_frequency %></changefreq>
<priority><%= $page->search_priority %></priority>
<lastmod><%= $page->date->strftime( '%Y-%m-%d' ) %></lastmod>
</url>
% }
</urlset>