Initial commit
This commit is contained in:
3
templates/views/attributes.html
Normal file
3
templates/views/attributes.html
Normal file
@@ -0,0 +1,3 @@
|
||||
{% for key, value in certificate.attributes %}
|
||||
<span class="badge badge-info" title="{{ key }}={{ value }}">{{ value }}</span>
|
||||
{% endfor %}
|
270
templates/views/authority.html
Normal file
270
templates/views/authority.html
Normal file
@@ -0,0 +1,270 @@
|
||||
<div class="modal fade" id="request_submission_modal" role="dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title">Request submission</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<ul class="nav nav-pills" id="myTab" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#snippet-certidude" role="tab" aria-controls="certidude" aria-selected="true">Certidude</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#snippet-windows" role="tab" aria-controls="windows" aria-selected="false">Windows</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#snippet-unix" role="tab" aria-controls="unix" aria-selected="false">UNIX</a>
|
||||
</li>
|
||||
|
||||
{% if "openvpn" in session.service.protocols %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#snippet-openvpn" role="tab" aria-controls="openvpn" aria-selected="false">OpenVPN</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if "ikev2" in session.service.protocols %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#snippet-strongswan" role="tab" aria-controls="strongswan" aria-selected="false">StrongSwan</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#snippet-lede" role="tab" aria-controls="lede" aria-selected="false">LEDE</a>
|
||||
</li>
|
||||
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" id="contact-tab" data-toggle="tab" href="#snippet-copypaste" role="tab" aria-controls="copypaste" aria-selected="false">Copypasta</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<div class="tab-content" id="myTabContent">
|
||||
<!-- Certidude client -->
|
||||
<div class="tab-pane fade show active" id="snippet-certidude" role="tabpanel" aria-labelledby="certidude">
|
||||
<p>On Ubuntu or Fedora:</p>
|
||||
<div class="highlight">
|
||||
<pre class="code"><code>{% include "snippets/certidude-client.sh" %}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Windows -->
|
||||
<div class="tab-pane fade" id="snippet-windows" role="tabpanel" aria-labelledby="windows">
|
||||
<p>On Windows execute following PowerShell script</p>
|
||||
{% if "ikev2" in session.service.protocols %}
|
||||
<div class="highlight"><pre class="code"><code>{% include "snippets/windows.ps1" %}</code></pre></div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- UNIX-like -->
|
||||
<div class="tab-pane fade" id="snippet-unix" role="tabpanel" aria-labelledby="unix">
|
||||
<p>For client certificates generate key pair and submit the signing request with common name set to short hostname:</p>
|
||||
<div class="highlight">
|
||||
<pre class="code"><code>{% include "snippets/request-client.sh" %}</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- OpenVPN as client -->
|
||||
<div class="tab-pane fade" id="snippet-openvpn" role="tabpanel" aria-labelledby="openvpn">
|
||||
<p>First acquire certificates using the snippet above.</p>
|
||||
<p>Then install software:</p>
|
||||
<div class="highlight"><pre class="code"><code>{% include "snippets/openvpn-client.sh" %}</code></pre></div>
|
||||
</div>
|
||||
|
||||
<!-- StrongSwan as client -->
|
||||
<div class="tab-pane fade" id="snippet-strongswan" role="tabpanel" aria-labelledby="strongswan">
|
||||
<p>First acquire certificates using the snippet above.</p>
|
||||
|
||||
<p>Then install software:</p>
|
||||
<div class="highlight">
|
||||
<pre class="code"><code>{% include "snippets/strongswan-patching.sh" %}</code></pre>
|
||||
</div>
|
||||
|
||||
<p>To configure StrongSwan as roadwarrior:</p>
|
||||
<div class="highlight"><pre class="code"><code>{% include "snippets/strongswan-client.sh" %}</code></pre></div>
|
||||
</div>
|
||||
|
||||
<!-- Copy & paste -->
|
||||
<div class="tab-pane fade" id="snippet-copypaste" role="tabpanel" aria-labelledby="copypaste">
|
||||
<p>Use whatever tools you have available on your platform to generate
|
||||
keypair and just paste ASCII armored PEM file contents here and hit submit:</p>
|
||||
|
||||
<form action="/api/request/" method="post">
|
||||
<textarea id="request_body" style="width:100%; min-height: 10em;"
|
||||
placeholder="-----BEGIN CERTIFICATE REQUEST-----"></textarea>
|
||||
<div class="modal-footer">
|
||||
<div class="btn-group">
|
||||
<button type="button" onclick="onSubmitRequest();" class="btn btn-primary"><i class="fa fa-upload"></i> Submit</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal"><i class="fa fa-ban"></i> Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="revocation_list_modal" role="dialog">
|
||||
<div class="modal-dialog modal-lg">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal">×</button>
|
||||
<h4 class="modal-title">Revocation lists</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>To fetch <a href="http://{{ authority.namespace }}/api/revoked/">certificate revocation list</a>:</p>
|
||||
<pre><code>curl http://{{ authority.namespace }}/api/revoked/ > crl.der
|
||||
curl http://{{ authority.namespace }}/api/revoked/ -L -H "Accept: application/x-pem-file"
|
||||
curl http://{{ authority.namespace }}/api/revoked/?wait=yes -L -H "Accept: application/x-pem-file" > crl.pem</code></pre>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn" data-dismiss="modal">Close</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-6 col-lg-4 col-xl-3">
|
||||
<h3>Signed certificates</h3>
|
||||
|
||||
<p>Authority administration
|
||||
{% if authority.certificate.organization %}of {{ authority.certificate.organization }}{% endif %}
|
||||
allowed for
|
||||
{% for user in session.authorization.admin_users %}<a href="mailto:{{ user.mail}}">{{ user.given_name }} {{user.surname }}</a>{% if not loop.last %}, {% endif %}{% endfor %} from {% if "0.0.0.0/0" in session.authorization.admin_subnets %}anywhere{% else %}
|
||||
{% for subnet in session.authorization.admin_subnets %}{{ subnet }}{% if not loop.last %}, {% endif %}{% endfor %}{% endif %}.
|
||||
Authority valid from
|
||||
<time class="timeago" datetime="{{ authority.certificate.signed }}">{{ authority.certificate.signed }}</time>
|
||||
until
|
||||
<time class="timeago" datetime="{{ authority.certificate.expires }}">{{ authority.certificate.expires }}</time>.
|
||||
Authority certificate can be downloaded from <a href="/api/certificate/">here</a>.
|
||||
Following certificates have been signed:</p>
|
||||
|
||||
<div id="signed-filter" class="btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-primary"><input id="signed-filter-new" type="checkbox" autocomplete="off">New</label>
|
||||
<label class="btn btn-primary active"><input id="signed-filter-online" type="checkbox" autocomplete="off" checked>Online</label>
|
||||
<label class="btn btn-primary"><input id="signed-filter-offline" type="checkbox" autocomplete="off">Lately seen</label>
|
||||
<label class="btn btn-primary"><input id="signed-filter-dead" type="checkbox" autocomplete="off">Gone</label>
|
||||
</div>
|
||||
|
||||
<div id="signed_certificates">
|
||||
{% for certificate in session.signed | sort(attribute="signed", reverse=true) %}
|
||||
{% include "views/signed.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<p>Showing <span id="signed-filter-counter">-</span> of total <span id="signed-total">-</span> certificates</p>
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-4 col-xl-3">
|
||||
{% if session.features.token %}
|
||||
<h3>Tokens</h3>
|
||||
<p>Tokens allow enrolling smartphones and third party devices.</p>
|
||||
<ul>
|
||||
<li>You can issue yourself a token to be used on a mobile device</li>
|
||||
<li>Enter username to issue a token to issue a token for another user</li>
|
||||
<li>Enter e-mail address to issue a token to guest users outside domain</li>
|
||||
</ul>
|
||||
<p>
|
||||
<div class="input-group">
|
||||
<input id="token_username" name="username" type="text" class="form-control" placeholder="Username" aria-describedby="sizing-addon2">
|
||||
<input id="token_mail" name="mail" type="mail" class="form-control" placeholder="Optional e-mail" aria-describedby="sizing-addon2">
|
||||
<span class="input-group-btn">
|
||||
<button class="btn btn-secondary" type="button" onClick="onIssueToken();"><i class="fa fa-send"></i> Send token</button>
|
||||
</span>
|
||||
</div>
|
||||
</p>
|
||||
|
||||
<p>Issued tokens:</p>
|
||||
<ul class="list-group">
|
||||
{% for token in session.tokens %}
|
||||
{% include "views/token.html" %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div id="token_qrcode"></div>
|
||||
{% endif %}
|
||||
|
||||
{% if session.authorization.request_subnets %}
|
||||
<p> </p>
|
||||
<h3>Pending requests</h3>
|
||||
|
||||
<p>Use Certidude client to apply for a certificate.
|
||||
|
||||
{% if not session.authorization.request_subnets %}
|
||||
Request submission disabled.
|
||||
{% elif "0.0.0.0/0" in session.authorization.request_subnets %}
|
||||
Request submission is enabled.
|
||||
{% else %}
|
||||
Request submission allowed from
|
||||
{% for subnet in session.authorization.request_subnets %}
|
||||
{{ subnet }}{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}.
|
||||
{% endif %}
|
||||
|
||||
See <a href="#request_submission_modal" data-toggle="modal">here</a> for more information on manual signing request upload.
|
||||
|
||||
{% if session.authorization.autosign_subnets %}
|
||||
{% if "0.0.0.0/0" in session.authorization.autosign_subnets %}
|
||||
All requests are automatically signed.
|
||||
{% else %}
|
||||
Requests from
|
||||
{% for subnet in session.authorization.autosign_subnets %}
|
||||
{{ subnet }}{% if not loop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
are automatically signed.
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
</p>
|
||||
<div id="pending_requests">
|
||||
{% for request in session.requests | sort(attribute="submitted", reverse=true) %}
|
||||
{% include "views/request.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if session.builder.profiles %}
|
||||
<h3>LEDE imagebuilder</h3>
|
||||
<p>Hit a link to generate machine specific image. Note that this might take couple minutes to finish.</p>
|
||||
<ul>
|
||||
{% for name, title, filename in session.builder.profiles %}
|
||||
<li><a href="/api/builder/{{ name }}/{{ filename }}">{{ title }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
<div class="col-sm-6 col-lg-4 col-xl-3">
|
||||
|
||||
<h3>Revoked certificates</h3>
|
||||
<p>Following certificates have been revoked{% if session.features.crl %}, for more information click
|
||||
<a href="#revocation_list_modal" data-toggle="modal">here</a>{% endif %}.</p>
|
||||
|
||||
{% for certificate in session.revoked | sort(attribute="revoked", reverse=true) %}
|
||||
{% include "views/revoked.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div id="column-log" class="col-sm-6 col-lg-4 col-xl-3 hidden-lg-down">
|
||||
<div class="loader-container">
|
||||
<div class="loader"></div>
|
||||
<p>Loading logs, this might take a while...</p>
|
||||
</div>
|
||||
<div class="content" style="display:none;">
|
||||
<h3>Log</h3>
|
||||
<div class="btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-primary active"><input id="log-level-critical" type="checkbox" autocomplete="off" checked>Critical</label>
|
||||
<label class="btn btn-primary active"><input id="log-level-error" type="checkbox" autocomplete="off" checked>Error</label>
|
||||
<label class="btn btn-primary active"><input id="log-level-warning" type="checkbox" autocomplete="off" checked>Warn</label>
|
||||
<label class="btn btn-primary active"><input id="log-level-info" type="checkbox" autocomplete="off" checked>Info</label>
|
||||
<label class="btn btn-primary"><input id="log-level-debug" type="checkbox" autocomplete="off">Debug</label>
|
||||
</div>
|
||||
<ul id="log-entries" class="list-group">
|
||||
</ul>
|
||||
<p>Click here to load more entries</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
31
templates/views/configuration.html
Normal file
31
templates/views/configuration.html
Normal file
@@ -0,0 +1,31 @@
|
||||
|
||||
<h1>Create a rule</h1>
|
||||
<p>
|
||||
|
||||
<datalist id="tag_autocomplete">
|
||||
|
||||
</datalist>
|
||||
|
||||
<span>Filter</span>
|
||||
<select id="tags_autocomplete"></select>
|
||||
attaches attribute
|
||||
<select>
|
||||
{% include 'views/tagtypes.html' %}
|
||||
</select>
|
||||
<span contenteditable>something</span>
|
||||
<button>Add rule</button>
|
||||
</p>
|
||||
|
||||
{% for grouper, items in configuration | groupby('tag_id') %}
|
||||
|
||||
<h1>Filter {{ items[0].match_key }} is {{ items[0].match_value }}</h1>
|
||||
<ul>
|
||||
|
||||
{% for item in items %}
|
||||
<li>Attach {{ item.key }} attribute {{ item.value }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
{% endfor %}
|
||||
|
||||
|
278
templates/views/enroll.html
Normal file
278
templates/views/enroll.html
Normal file
@@ -0,0 +1,278 @@
|
||||
<!-- https://wiki.strongswan.org/projects/strongswan/wiki/AppleIKEv2Profile#Certificate-authentication -->
|
||||
|
||||
<!--
|
||||
|
||||
Browser status
|
||||
|
||||
- Edge doesn't work because they think data: urls are insecure
|
||||
- iphone QR code scanner's webview is constrained, cant download data: links
|
||||
- outlook.com via iphone mail client works
|
||||
- android gmail app works
|
||||
- chrome works
|
||||
- firefox works
|
||||
|
||||
OS/soft status
|
||||
|
||||
- OpenVPN works on everything
|
||||
- StrongSwan app works on Android
|
||||
- NetworkManager doesn't support importing .sswan files yet, so no IPSec support for Ubuntu or Fedora here yet
|
||||
|
||||
-->
|
||||
|
||||
<div id="enroll" class="row">
|
||||
<div class="loader-container">
|
||||
<div class="loader"></div>
|
||||
<p>Generating RSA keypair, this will take a while...</p>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 edge-broken" style="display:none;">
|
||||
<!-- https://stackoverflow.com/questions/33154646/data-uri-link-a-href-data-doesnt-work-in-microsoft-edge?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa -->
|
||||
Microsoft Edge not supported, open the link with Chrome or Firefox
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option ubuntu linux openvpn">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Ubuntu 16.04+</h3>
|
||||
<p class="card-text">Install OpenVPN plugin for NetworkManager by executing following two command in the terminal:
|
||||
|
||||
<pre><code># Ubuntu 16.04 ships with older OpenVPN 2.3, to support newer ciphers add OpenVPN's repo
|
||||
if [ $(lsb_relase -cs) == "xenial" ]; then
|
||||
wget -O - https://swupdate.openvpn.net/repos/repo-public.gpg|apt-key add -
|
||||
echo "deb http://build.openvpn.net/debian/openvpn/release/2.4 xenial main" > /etc/apt/sources.list.d/openvpn-aptrepo.list
|
||||
apt update
|
||||
apt install openvpn
|
||||
fi
|
||||
|
||||
sudo apt install -y network-manager-openvpn-gnome
|
||||
sudo systemctl restart network-manager
|
||||
</code></pre>
|
||||
|
||||
<p>
|
||||
<a href="javascript:onEnroll('ovpn');" class="btn btn-primary">Fetch OpenVPN profile</a>
|
||||
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#ubuntu-screenshots" aria-expanded="false" aria-controls="ubuntu-screenshots">
|
||||
Screenshots
|
||||
</button>
|
||||
</p>
|
||||
|
||||
<div class="collapse" id="ubuntu-screenshots">
|
||||
<p>Open up network connections:</p>
|
||||
<p><img src="/img/ubuntu-01-edit-connections.png"/></p>
|
||||
<p>Hit <i>Add button</i>:</p>
|
||||
<p><img src="/img/ubuntu-02-network-connections.png"/></p>
|
||||
<p>Select <i>Import a saved VPN configuration...</i>:</p>
|
||||
<p><img src="/img/ubuntu-03-import-saved-config.png"/></p>
|
||||
<p>Select downloaded file:</p>
|
||||
<p><img src="/img/ubuntu-04-select-file.png"/></p>
|
||||
<p>Once profile is successfully imported following dialog appears:</p>
|
||||
<p><img src="/img/ubuntu-05-profile-imported.png"/></p>
|
||||
<p>By default all traffic is routed via VPN gateway, route only intranet subnets to the gateway select <i>Routes...</i> under <i>IPv4 Settings</i>:</p>
|
||||
<p><img src="/img/ubuntu-06-ipv4-settings.png"/></p>
|
||||
<p>Check <i>Use this connection only for resources on its network</i>:</p>
|
||||
<p><img src="/img/ubuntu-07-disable-default-route.png"/></p>
|
||||
<p>To activate the connection select it under <i>VPN Connections</i>:</p>
|
||||
<p><img src="/img/ubuntu-08-activate-connection.png"/></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option ubuntu linux openvpn advanced">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Ubuntu 18.04+ (advanced)</h3>
|
||||
<p class="card-text">Copy-paste follownig to terminal as root user:</p>
|
||||
<pre><code>{% include "snippets/request-client.sh" %}
|
||||
cat << EOF > '/etc/NetworkManager/system-connections/OpenVPN to {{ authority.namespace }}'
|
||||
{% include "snippets/networkmanager-openvpn.conf" %}EOF
|
||||
|
||||
nmcli con reload
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option ubuntu linux ikev2 advanced">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Ubuntu 18.04+ (advanced)</h3>
|
||||
<p class="card-text">Copy-paste follownig to terminal as root user:</p>
|
||||
<pre><code>{% include "snippets/request-client.sh" %}
|
||||
cat << EOF > '/etc/NetworkManager/system-connections/IPSec to {{ authority.namespace }}'
|
||||
{% include "snippets/networkmanager-strongswan.conf" %}EOF
|
||||
|
||||
nmcli con reload
|
||||
</code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-sm-12 mt-3 option fedora linux openvpn">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Fedora</h3>
|
||||
<p class="card-text">Install OpenVPN plugin for NetworkManager by running following two commands:</p>
|
||||
<pre><code>dnf install NetworkManager-openvpn-gnome
|
||||
systemctl restart NetworkManager</code></pre>
|
||||
Right click in the NetworkManager icon, select network settings. Hit the + button and select <i>Import from file...</i>, select the downloaded .ovpn file.
|
||||
Remove the .ovpn file from the Downloads folder.</p>
|
||||
<a href="javascript:onEnroll('ovpn');" class="btn btn-primary">Fetch OpenVPN profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option windows ipsec">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Windows</h3>
|
||||
<p class="card-text">
|
||||
Import PKCS#12 container to your machine trust store.
|
||||
Import VPN connection profile by moving the downloaded .pbk file to
|
||||
<pre><code>%userprofile%\AppData\Roaming\Microsoft\Network\Connections\PBK</code></pre>
|
||||
or
|
||||
<pre><code>C:\ProgramData\Microsoft\Network\Connections\Pbk</code></pre></p>
|
||||
<a href="javascript:onEnroll('p12');" class="btn btn-primary">Fetch PKCS#12 container</a>
|
||||
<a href="#" class="btn btn-secondary">Fetch IPSec IKEv2 VPN profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option windows ikev2">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Windows</h3>
|
||||
<p>To configure IPSec IKEv2 tunnel on Windows, open PowerShell as administrator and copy-paste following:</p>
|
||||
<div class="highlight"><pre class="code"><code>{% include "snippets/windows.ps1" %}</code></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option windows openvpn">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Windows</h3>
|
||||
<p class="card-text">
|
||||
Install OpenVPN community edition client.
|
||||
Move the downloaded .ovpn file to C:\Program Files\OpenVPN\config and
|
||||
right click in the system tray on OpenVPN icon and select Connect from the menu.
|
||||
For finishing touch adjust the file permissions so only local
|
||||
administrator can read that file, remove regular user access to the file.
|
||||
</p>
|
||||
<a href="https://openvpn.net/index.php/download/community-downloads.html" class="btn btn-secondary">Get OpenVPN community edition</a>
|
||||
<a href="javascript:onEnroll('ovpn');" class="btn btn-primary">Fetch OpenVPN profile</a>
|
||||
<button class="btn btn-secondary" type="button" data-toggle="collapse" data-target="#windows-screenshots" aria-expanded="false" aria-controls="windows-screenshots">
|
||||
Screenshots
|
||||
</button>
|
||||
|
||||
<div class="collapse" id="windows-screenshots">
|
||||
<p>Download OpenVPN from the link supplied above:</p>
|
||||
<p><img src="/img/windows-01-download-openvpn.png"/></p>
|
||||
|
||||
<p>Install OpenVPN:</p>
|
||||
<p><img src="/img/windows-02-install-openvpn.png"/></p>
|
||||
|
||||
<p>Move the configuraiton file downloaded from the second button above:</p>
|
||||
<p><img src="/img/windows-03-move-config-file.png"/></p>
|
||||
|
||||
<p>Connect from system tray:</p>
|
||||
<p><img src="/img/windows-04-connect.png"/></p>
|
||||
|
||||
<p>Connection is successfully configured:</p>
|
||||
<p><img src="/img/windows-05-connected.png"/></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option mac openvpn">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Mac OS X</h3>
|
||||
<p class="card-text">Download Tunnelblick. Tap on the button above and import the profile.</p>
|
||||
<a href="https://tunnelblick.net/" target="_blank" class="btn btn-secondary">Get Tunnelblick</a>
|
||||
<a href="javascript:onEnroll('ovpn');" class="btn btn-primary">Fetch OpenVPN profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option iphone ipad openvpn">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">iPhone/iPad</h3>
|
||||
<p class="card-text">Install OpenVPN Connect app, tap on the button below.</p>
|
||||
<a href="https://itunes.apple.com/us/app/openvpn-connect/id590379981?mt=8" target="_blank" class="btn btn-secondary">Get OpenVPN Connect app</a>
|
||||
<a href="javascript:onEnroll('ovpn');" class="btn btn-primary">Fetch OpenVPN profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option iphone ipad ikev2">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">iPhone/iPad</h3>
|
||||
<p class="card-text">
|
||||
Tap the button below, you'll be prompted about configuration profile, tap <i>Allow</i>.
|
||||
Hit <i>Install</i> in the top-right corner.
|
||||
Enter your passcode to unlock trust store.
|
||||
Tap <i>Install</i> and confirm by hitting <i>Install</i>.
|
||||
Where password for the certificate is prompted, enter 1234.
|
||||
Hit <i>Done</i>. Go to <i>Settings</i>, open VPN submenu and tap on the VPN profile to connect.
|
||||
</p>
|
||||
<a href="javascript:onEnroll('mobileconfig');" class="btn btn-primary">Fetch IPSec IKEv2 VPN profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option mac ikev2">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Mac OS X</h3>
|
||||
<p class="card-text">
|
||||
Click on the button below, you'll be prompted about configuration profile, tap <i>Allow</i>.
|
||||
Hit <i>Install</i> in the top-right corner.
|
||||
Enter your passcode to unlock trust store.
|
||||
Tap <i>Install</i> and confirm by hitting <i>Install</i>.
|
||||
Where password for the certificate is prompted, enter 1234.
|
||||
Hit <i>Done</i>. Go to <i>Settings</i>, open VPN submenu and tap on the VPN profile to connect.
|
||||
</p>
|
||||
<a href="javascript:onEnroll('mobileconfig');" class="btn btn-primary">Fetch VPN profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option android openvpn">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Android</h3>
|
||||
<p class="card-text">Intall OpenVPN Connect app on your device.
|
||||
Tap on the downloaded .ovpn file, OpenVPN Connect should prompt for import.
|
||||
Hit <i>Accept</i> and then <i>Connect</i>.
|
||||
Remember to delete any remaining .ovpn files under the <i>Downloads</i>.
|
||||
</p>
|
||||
<a href="https://play.google.com/store/apps/details?id=net.openvpn.openvpn" target="_blank" class="btn btn-secondary">Get OpenVPN Connect app</a>
|
||||
<a href="javascript:onEnroll('ovpn');" class="btn btn-primary">Fetch OpenVPN profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12 mt-3 option android ikev2">
|
||||
<div class="card">
|
||||
<div class="card-block">
|
||||
<h3 class="card-title">Android</h3>
|
||||
<p class="card-text">
|
||||
Install strongSwan Client app on your device.
|
||||
Tap on the downloaded .sswan file, StrongSwan Client should prompt for import.
|
||||
Hit <i>Import certificate from VPN profile</i> and then <i>Import</i> in the top-right corner.
|
||||
Remember to delete any remaining .sswan files under the <i>Downloads</i>.
|
||||
</p>
|
||||
<a href="https://play.google.com/store/apps/details?id=org.strongswan.android" class="btn btn-secondary">Get strongSwan VPN Client app</a>
|
||||
<a href="javascript:onEnroll('sswan');" class="btn btn-primary">Fetch StrongSwan profile</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-12 mt-3 option any">
|
||||
<a href="javascript:$('.option').show();">I did't find an appropriate option for me, show all options</a>
|
||||
</div>
|
||||
|
||||
</div>
|
2
templates/views/error.html
Normal file
2
templates/views/error.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<h1>{{ message.title }}</h1>
|
||||
<p>{{ message.description }}</p>
|
14
templates/views/insecure.html
Normal file
14
templates/views/insecure.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<p>You're viewing this page over insecure channel.
|
||||
You can give it a try and <a href="https://{{ authority.hostname }}">connect over HTTPS</a>,
|
||||
if that succeeds all subsequents accesses of this page will go over HTTPS.
|
||||
</p>
|
||||
<p>
|
||||
Click <a href="/api/certificate">here</a> to fetch the certificate of this authority.
|
||||
Alternatively install certificate on Fedora or Ubuntu with following copy-pastable snippet:
|
||||
</p>
|
||||
|
||||
<div class="highlight">
|
||||
<pre class="code"><code>{% include "snippets/store-authority.sh" %}
|
||||
{% include "snippets/update-trust.sh" %}</code></pre>
|
||||
</div>
|
||||
|
7
templates/views/lease.html
Normal file
7
templates/views/lease.html
Normal file
@@ -0,0 +1,7 @@
|
||||
Last seen
|
||||
<time class="timeago" datetime="{{ certificate.lease.last_seen }}">{{ certificate.lease.last_seen }}</time>
|
||||
at
|
||||
<a target="_blank" href="http://{{ certificate.lease.inner_address }}">{{ certificate.lease.inner_address }}</a>{% if certificate.lease.outer_address %}
|
||||
from
|
||||
<a target="{{ certificate.lease.outer_address }}" href="https://geoiplookup.net/ip/{{ certificate.lease.outer_address }}">{{ certificate.lease.outer_address }}</a>{% endif %}.
|
||||
See some stats <a href="http://172.20.1.19:19999/host/{{ certificate.common_name }}/" target="_blank">here</a>.
|
8
templates/views/logentry.html
Normal file
8
templates/views/logentry.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<li id="log_entry_{{ entry.id }}" data-keywords="{{ entry.message }}" class="list-group-item justify-content-between filterable{% if entry.fresh %} fresh{% endif %}">
|
||||
<span>
|
||||
<i class="fa fa-{{ entry.severity }}-circle"></i>
|
||||
{{ entry.message }}
|
||||
</span>
|
||||
<span class="badge badge-default badge-pill">{{ entry.created }}</span>
|
||||
</li>
|
||||
|
64
templates/views/request.html
Normal file
64
templates/views/request.html
Normal file
@@ -0,0 +1,64 @@
|
||||
<div id="request-{{ request.id }}" class="card filterable mt-3"
|
||||
data-keywords="{{ request.common_name }}|" data-id="{{request.id}}">
|
||||
<div class="card-header">
|
||||
{% if certificate.server %}
|
||||
<i class="fa fa-server"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-laptop"></i>
|
||||
{% endif %}
|
||||
{{ request.common_name }}
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<p class="mb-1">
|
||||
Submitted
|
||||
<time class="timeago" datetime="{{ request.submitted }}">Request was submitted {{ request.submitted }}</time>
|
||||
from
|
||||
{% if request.hostname %}{{request.hostname}} ({{request.address}}){% else %}{{request.address}}{% endif %}
|
||||
</p>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-secondary" data-toggle="collapse" data-target="#details-{{ request.sha256sum }}"><i class="fa fa-list"></i> Details</button>
|
||||
<button type="button" class="btn btn-danger"
|
||||
data-loading-text="<i class='fa fa-circle-o-notch fa-spin'></i> Rejecting..."
|
||||
onclick="onRejectRequest(event, '{{ request.common_name }}', '{{ request.sha256sum }}');">
|
||||
<i class="fa fa-trash"></i> Reject</button>
|
||||
<button type="button" class="btn btn-success"
|
||||
data-loading-text="<i class='fa fa-circle-o-notch fa-spin'></i> Processing Order"
|
||||
onclick="onSignRequest(event, '{{ request.common_name }}', '{{ request.sha256sum }}');">
|
||||
<i class="fa fa-thumbs-up"></i> Approve</button>
|
||||
<button type="button" class="btn btn-success dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
{% for p in authority.signature.profiles %}
|
||||
<a class="dropdown-item{% if not request.common_name.match(p.common_name) %} disabled{% endif %}"
|
||||
{% if not request.common_name.match(p.common_name) %} title="Common name doesn't match expression {{ p.common_name }}"{% endif %}
|
||||
href="#" onclick="javascript:$.ajax({url:'/api/request/{{request.common_name}}/?sha256sum={{ request.sha256sum }}&profile={{ p.key }}',type:'post'});">
|
||||
{{ p.key }}, expires in {{ p.lifetime }} days</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse" id="details-{{ request.sha256sum }}">
|
||||
<p>Use following to fetch the signing request:</p>
|
||||
<div class="bd-example">
|
||||
<pre><code class="language-sh" data-lang="sh">wget <a href="/api/request/{{ request.common_name }}/">http://{{ authority.namespace }}/api/request/{{ request.common_name }}/</a>
|
||||
curl -L http://{{ authority.namespace }}/api/request/{{ request.common_name }}/ \
|
||||
| openssl req -text -noout</code></pre>
|
||||
</div>
|
||||
|
||||
<div style="overflow: auto; max-width: 100%;">
|
||||
<table class="table" id="signed_certificates">
|
||||
<tbody>
|
||||
<tr><th>Common name</th><td>{{ request.common_name }}</td></tr>
|
||||
<tr><th>Submitted</th><td>{{ request.submitted | datetime }}
|
||||
{% if request.address %}from {{ request.address }}
|
||||
{% if request.hostname %} ({{ request.hostname }}){% endif %}{% endif %}</td></tr>
|
||||
<tr><th>MD5</th><td>{{ request.md5sum }}</td></tr>
|
||||
<tr><th>SHA1</th><td>{{ request.sha1sum }}</td></tr>
|
||||
<tr><th>SHA256</th><td>{{ request.sha256sum }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
69
templates/views/revoked.html
Normal file
69
templates/views/revoked.html
Normal file
@@ -0,0 +1,69 @@
|
||||
<div id="certificate-{{ certificate.common_name | replace('@', '--') | replace('.', '-') }}" class="card filterable mt-3"
|
||||
data-keywords="{{ certificate.common_name }}|">
|
||||
<div class="card-body">
|
||||
<div class="card-header">
|
||||
{% if certificate.server %}
|
||||
<i class="fa fa-server"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-laptop"></i>
|
||||
{% endif %}
|
||||
{{ certificate.common_name }}
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<p>
|
||||
Serial number {{ certificate.serial | serial }}.
|
||||
</p>
|
||||
<p>
|
||||
Revoked
|
||||
<time class="timeago" datetime="{{ certificate.revoked }}">Certificate revoked {{ certificate.revoked }}</time>.
|
||||
Valid from {{ certificate.signed | datetime }} to {{ certificate.expired | datetime }}.
|
||||
</p>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-secondary" data-toggle="collapse" data-target="#details-{{ certificate.sha256sum }}"><i class="fa fa-list"></i> Details</button>
|
||||
<div class="btn-group">
|
||||
<a href="/api/signed/{{ certificate.common_name }}/" class="btn btn-secondary hidden-xs-down"><i class="fa fa-download"></i> Download</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse" id="details-{{ certificate.sha256sum }}">
|
||||
<p>To fetch certificate:</p>
|
||||
|
||||
<div class="bd-example">
|
||||
<pre><code class="language-sh" data-lang="sh">wget <a href="/api/revoked/{{ certificate.serial }}/">http://{{ authority.namespace }}/api/revoked/{{ certificate.serial }}/</a>
|
||||
curl http://{{ authority.namespace }}/api/revoked/{{ certificate.serial }}/ \
|
||||
| openssl x509 -text -noout</code></pre>
|
||||
</div>
|
||||
|
||||
<p>To perform online certificate status request</p>
|
||||
<pre><code class="language-bash" data-lang="bash">curl http://{{ authority.namespace }}/api/certificate/ > session.pem
|
||||
openssl ocsp -issuer session.pem -CAfile session.pem \
|
||||
-url http://{{ authority.namespace }}/api/ocsp/ \
|
||||
-serial 0x{{ certificate.serial }}</span></code></pre>
|
||||
|
||||
<p>
|
||||
<table class="table" id="signed_certificates">
|
||||
<tbody>
|
||||
<tr><th>Common name</th><td>{{ certificate.common_name }}</td></tr>
|
||||
<tr><th>Organizational unit</th><td>{{ certificate.organizational_unit }}</td></tr>
|
||||
<tr><th>Serial number</th><td>{{ certificate.serial }}</td></tr>
|
||||
<tr><th>Signed</th><td>{{ certificate.signed | datetime }}
|
||||
{% if certificate.signer %}, by {{ certificate.signer }}{% endif %}</td></tr>
|
||||
<tr><th>Expired</th><td>{{ certificate.expired | datetime }}</td></tr>
|
||||
{% if certificate.lease %}
|
||||
<tr><th>Lease</th><td><a href="http://{{ certificate.lease.inner_address }}">{{ certificate.lease.inner_address }}</a> at {{ certificate.lease.last_seen | datetime }}
|
||||
from <a href="https://geoiptool.com/en/?ip={{ certificate.lease.outer_address }}" target="_blank">{{ certificate.lease.outer_address }}</a>
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
|
||||
<!--
|
||||
<tr><th>MD5</th><td>{{ certificate.md5sum }}</td></tr>
|
||||
<tr><th>SHA1</th><td>{{ certificate.sha1sum }}</td></tr>
|
||||
-->
|
||||
<tr><th>SHA256</th><td>{{ certificate.sha256sum }}</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
134
templates/views/signed.html
Normal file
134
templates/views/signed.html
Normal file
@@ -0,0 +1,134 @@
|
||||
<div id="certificate-{{ certificate.id }}" class="card filterable mt-3"
|
||||
{% if certificate.lease %}data-last-seen={{ certificate.lease.last_seen }}{% endif %}
|
||||
data-keywords="{{ certificate.common_name }}|{% if session.tagging %}{% for tag in certificate.tags %}{{ tag.id }}|{% endfor %}{% endif %}{% for key, value in certificate.attributes %}{{ key }}={{ value }}|{% endfor %}" data-id="{{certificate.id}}">
|
||||
<div class="card-header">
|
||||
{% if certificate.organizational_unit %}
|
||||
<i class="fa fa-folder" aria-hidden="true"></i>
|
||||
{{ certificate.organizational_unit }} /
|
||||
{% endif %}
|
||||
{% if certificate.extensions.extended_key_usage and "server_auth" in certificate.extensions.extended_key_usage %}
|
||||
<i class="fa fa-server"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-laptop"></i>
|
||||
{% endif %}
|
||||
{{ certificate.common_name }}
|
||||
</div>
|
||||
<div class="card-block">
|
||||
<p>
|
||||
<i class="fa fa-circle"></i>
|
||||
<span class="lease">
|
||||
{% if certificate.lease %}
|
||||
{% include "views/lease.html" %}
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
Signed
|
||||
<time class="timeago" datetime="{{ certificate.signed }}">Certificate was signed {{ certificate.signed }}</time>{% if certificate.signer %} by {{ certificate.signer }}{% endif %},
|
||||
expires
|
||||
<time class="timeago" datetime="{{ certificate.expires }}">Certificate expires {{ certificate.expires }}</time>.
|
||||
</p>
|
||||
<p>
|
||||
{% if session.tagging %}
|
||||
<span class="tags" data-cn="{{ certificate.common_name }}">
|
||||
{% include "views/tags.html" %}
|
||||
</span>
|
||||
{% endif %}
|
||||
<span class="attributes" data-cn="{{ certificate.common_name }}">
|
||||
{% include "views/attributes.html" %}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-secondary" data-toggle="collapse" data-target="#details-{{ certificate.sha256sum }}"><i class="fa fa-list"></i> Details</button>
|
||||
<button type="button" class="btn btn-danger"
|
||||
onclick="javascript:$(this).button('loading');$.ajax({url:'/api/signed/{{certificate.common_name}}/?sha256sum={{ certificate.sha256sum }}',type:'delete'});">
|
||||
<i class="fa fa-ban"></i> Revoke</button>
|
||||
<button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="#"
|
||||
onclick="javascript:$(this).button('loading');$.ajax({url:'/api/signed/{{certificate.common_name}}/?sha256sum={{ certificate.sha256sum }}&reason=key_compromise',type:'delete'});">Revoke due to key compromise</a>
|
||||
<a class="dropdown-item" href="#"
|
||||
onclick="javascript:$(this).button('loading');$.ajax({url:'/api/signed/{{certificate.common_name}}/?sha256sum={{ certificate.sha256sum }}&reason=cessation_of_operation',type:'delete'});">Revoke due to cessation of operation</a>
|
||||
<a class="dropdown-item" href="#"
|
||||
onclick="javascript:$(this).button('loading');$.ajax({url:'/api/signed/{{certificate.common_name}}/?sha256sum={{ certificate.sha256sum }}&reason=privilege_withdrawn',type:'delete'});">Revoke due to withdrawn privilege</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="btn-group">
|
||||
{% if session.tagging %}
|
||||
<button type="button" class="btn btn-default" onclick="onNewTagClicked(event);" data-key="other" data-cn="{{ certificate.common_name }}">
|
||||
<i class="fa fa-tag"></i> Tag</button>
|
||||
<button type="button" class="btn btn-default dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="sr-only">Toggle Dropdown</span>
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
{% for tag_category in session.tagging %}
|
||||
<a class="dropdown-item" href="#" data-key="{{ tag_category.name }}" data-cn="{{ certificate.common_name }}"
|
||||
onclick="onNewTagClicked(event);">{{ tag_category.title }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="collapse" id="details-{{ certificate.sha256sum }}">
|
||||
<p>To launch shell for this device, click <a href="#" onclick="onLaunchShell('{{ certificate.common_name }}')">here</a>
|
||||
<p>To fetch certificate:</p>
|
||||
|
||||
<div class="bd-example">
|
||||
<pre><code class="language-sh" data-lang="sh">wget <a href="/api/signed/{{ certificate.common_name }}/">http://{{ authority.namespace }}/api/signed/{{ certificate.common_name }}</a>
|
||||
curl -L http://{{ authority.namespace }}/api/signed/{{ certificate.common_name }}/ \
|
||||
| openssl x509 -text -noout</code></pre>
|
||||
</div>
|
||||
|
||||
{% if session.authorization.ocsp_subnets %}
|
||||
{% if certificate.responder_url %}
|
||||
<p>To perform online certificate status request{% if "0.0.0.0/0" not in session.authorization.ocsp_subnets %}
|
||||
from whitelisted {{ session.authorization.ocsp_subnets }} subnets{% endif %}:</p>
|
||||
<pre><code class="language-bash" data-lang="bash">curl http://{{ authority.namespace }}/api/certificate > session.pem
|
||||
openssl ocsp -issuer session.pem -CAfile session.pem \
|
||||
-url {{ certificate.responder_url }} \
|
||||
-serial 0x{{ certificate.serial }}</code></pre>
|
||||
{% else %}
|
||||
<p>Querying OCSP responder disabled for this certificate, see /etc/certidude/profile.conf how to enable if that's desired</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<p>To fetch script:</p>
|
||||
<pre><code class="language-bash" data-lang="bash">curl -L --cert-status https://{{ authority.namespace }}:8443/api/signed/{{ certificate.common_name }}/script/ \
|
||||
--cacert /etc/certidude/authority/{{ authority.namespace }}/ca_cert.pem \
|
||||
--key /etc/certidude/authority/{{ authority.namespace }}/host_key.pem \
|
||||
--cert /etc/certidude/authority/{{ authority.namespace }}/host_cert.pem</pre></code>
|
||||
|
||||
<div style="overflow: auto; max-width: 100%;">
|
||||
<table class="table" id="signed_certificates">
|
||||
<tbody>
|
||||
<tr><th>Common name</th><td>{{ certificate.common_name }}</td></tr>
|
||||
<tr><th>Organizational unit</th><td>{% if certificate.organizational_unit %}{{ certificate.organizational_unit }}{% else %}-{% endif %}</td></tr>
|
||||
<tr><th>Serial number</th><td style="word-wrap:break-word;">{{ certificate.serial | serial }}</td></tr>
|
||||
<tr><th>Signed</th><td>{{ certificate.signed | datetime }}{% if certificate.signer %} by {{ certificate.signer }}{% endif %}</td></tr>
|
||||
<tr><th>Expires</th><td>{{ certificate.expires | datetime }}</td></tr>
|
||||
{% if certificate.lease %}
|
||||
<tr><th>Lease</th><td><a href="http://{{ certificate.lease.inner_address }}">{{ certificate.lease.inner_address }}</a> at {{ certificate.lease.last_seen | datetime }}
|
||||
from <a href="https://geoiptool.com/en/?ip={{ certificate.lease.outer_address }}" target="_blank">{{ certificate.lease.outer_address }}</a>
|
||||
</td></tr>
|
||||
{% endif %}
|
||||
|
||||
<!--
|
||||
<tr><th>MD5</th><td>{{ certificate.md5sum }}</td></tr>
|
||||
<tr><th>SHA1</th><td>{{ certificate.sha1sum }}</td></tr>
|
||||
-->
|
||||
<tr><th>SHA256</th><td style="word-wrap:break-word; overflow-wrap: break-word; ">{{ certificate.sha256sum }}</td></tr>
|
||||
{% if certificate.key_usage %}
|
||||
<tr><th>Key usage</th><td>{{ certificate.key_usage | join(", ") | replace("_", " ") }}</td></tr>
|
||||
{% endif %}
|
||||
{% if certificate.extended_key_usage %}
|
||||
<tr><th>Extended key usage</th><td>{{ certificate.extended_key_usage | join(", ") | replace("_", " ") }}</td></tr>
|
||||
{% endif %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
6
templates/views/tags.html
Normal file
6
templates/views/tags.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% for tag in certificate.tags %}
|
||||
<span data-cn="{{ certificate.common_name }}"
|
||||
title="{{ tag }}"
|
||||
class="badge badge-default"
|
||||
onClick="onTagClicked(event);">{{ tag }}</span>
|
||||
{% endfor %}
|
10
templates/views/token.html
Normal file
10
templates/views/token.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<li id="token-{{ token.subject }}-{{ token.uuid }}" class="list-group-item filterable" data-keywords="">
|
||||
<span>
|
||||
<i class="fas fa-ticket-alt"></i>
|
||||
{{ token.uuid }}...
|
||||
<a href="mailto:{{ token.mail }}">{{ token.subject }}</a>
|
||||
{% if token.issuer %}{% if token.issuer != token.subject %}by {{ token.issuer }}{% else %}by himself{% endif %}{% else %}via shell{% endif %},
|
||||
expires
|
||||
<time class="timeago" datetime="{{ token.expires }}">{{ token.expires }}</time>
|
||||
</span>
|
||||
</li>
|
Reference in New Issue
Block a user