mirror of
https://github.com/cunnie/sslip.io.git
synced 2025-10-04 07:16:33 +08:00

To make room for the k-v.io HTML website, we rename the `document_root` of the sslip.io website to the more explicit `document_root_sslip.io`.
413 lines
22 KiB
HTML
413 lines
22 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta name="generator" content="HTML Tidy for HTML5 for Apple macOS version 5.8.0">
|
||
<meta charset="utf-8">
|
||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<!-- The above 3 meta tags *must* come first in the head; any
|
||
other head content must come *after* these tags -->
|
||
<title>Welcome to sslip.io</title>
|
||
<meta name="description" content="sslip.io">
|
||
<meta name="author" content="Brian Cunnie"><!-- cute Green Lock icon -->
|
||
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico"><!-- Latest
|
||
compiled and minified CSS -->
|
||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"><!--
|
||
Optional theme -->
|
||
<link rel="stylesheet" href="css/starter-template.css"><!--
|
||
HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
|
||
<!--
|
||
WARNING: Respond.js doesn't work if you view the page via file:// -->
|
||
<!--[if lt
|
||
IE 9]> <script
|
||
src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script
|
||
src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]-->
|
||
</head>
|
||
<body>
|
||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||
<div class="container">
|
||
<div class="navbar-header">
|
||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar"
|
||
aria-expanded="false" aria-controls="navbar"><span class="sr-only">Toggle navigation</span></button> <a class=
|
||
"navbar-brand" href="/">sslip.io</a>
|
||
</div>
|
||
<div id="navbar" class="collapse navbar-collapse">
|
||
<ul class="nav navbar-nav">
|
||
<li class="active">
|
||
<a href="/">Home</a>
|
||
</li><!--
|
||
<li><a href="faq.html">FAQ</a></li>
|
||
<li><a href="about.html">About</a></li>
|
||
-->
|
||
</ul>
|
||
</div><!--/.nav-collapse -->
|
||
</div>
|
||
</nav>
|
||
<div class="container">
|
||
<div class="starter-template">
|
||
<h3 id="sslip.io">sslip.io</h3>
|
||
<p>Operational Status: <a href="https://ci.nono.io/teams/main/pipelines/sslip.io"><img src=
|
||
"https://ci.nono.io/api/v1/pipelines/sslip.io/jobs/dns-servers/badge" alt="ci.nono.io"></a> <sup><a href=
|
||
"#status" class="alert-link">[Status]</a></sup></p>
|
||
<p><em>sslip.io</em> is a DNS (<a href="https://en.wikipedia.org/wiki/Domain_Name_System">Domain Name System</a>)
|
||
service that, when queried with a hostname with an embedded IP address, returns that IP address. It was inspired
|
||
by <a href="http://xip.io">xip.io</a>, which was created by <a href="https://github.com/sstephenson">Sam
|
||
Stephenson</a>.</p>
|
||
<p>Here are some examples:</p>
|
||
<table class="table">
|
||
<thead>
|
||
<tr class="header">
|
||
<th>Hostname / URL</th>
|
||
<th>IP Address</th>
|
||
<th>Notes</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td>
|
||
<a href="https://104.155.144.4.sslip.io">https://104.155.144.4.sslip.io</a>
|
||
</td>
|
||
<td>104.155.144.4</td>
|
||
<td>dot separators, sslip.io website mirror (IPv4)</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td>
|
||
<a href="https://52-0-56-137.sslip.io">https://52-0-56-137.sslip.io</a>
|
||
</td>
|
||
<td>52.0.56.137</td>
|
||
<td>dash separators, sslip.io website mirror (IPv4)</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td>www.192.168.0.1.sslip.io</td>
|
||
<td>192.168.0.1</td>
|
||
<td>subdomain</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td>www.192-168-0-1.sslip.io</td>
|
||
<td>192.168.0.1</td>
|
||
<td>subdomain + dashes</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td>
|
||
<a href="https://www-78-46-204-247.sslip.io">https://www-78-46-204-247.sslip.io</a>
|
||
</td>
|
||
<td>78.46.204.247</td>
|
||
<td>dash prefix, sslip.io website mirror (IPv4)</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td>--1.sslip.io</td>
|
||
<td>::1</td>
|
||
<td>IPv6 — always use dashes, never dots</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td>
|
||
<a href="https://2a01-4f8-c17-b8f--2.sslip.io">https://2a01-4f8-c17-b8f--2.sslip.io</a>
|
||
</td>
|
||
<td>2a01:4f8:c17:b8f::2</td>
|
||
<td>sslip.io website mirror (IPv6)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h3 id="branding">Branding / White Label / Custom Domains</h3>
|
||
<p>sslip.io can be used to brand your own site (you don’t need to use the sslip.io domain). For example, say you
|
||
own the domain “example.com”, and you want your subdomain, “xip.example.com” to have xip.io-style features. To
|
||
accomplish this, set the following three DNS servers as NS records for the subdomain “xip.example.com”</p>
|
||
<div class="alert alert-warning" role="alert">
|
||
2021-11-27 FYI (for your information), we've switched to using our own nameservers (sslip.io) instead of the
|
||
old nono.io nameservers. <b>You don't need to change anything.</b> Don't worry if you're pointing to the old
|
||
nameservers—they'll continue to work properly. In fact, under the hood they are the same nameservers; the
|
||
change is merely cosmetic: we've created sslip.io DNS records for them.
|
||
</div>
|
||
<table class="table">
|
||
<thead>
|
||
<tr class="header">
|
||
<th>hostname</th>
|
||
<th>IP address</th>
|
||
<th>Location</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr class="odd">
|
||
<td><code>ns-aws.sslip.io.</code></td>
|
||
<td>52.0.56.137<br>
|
||
2600:1f18:aaf:6900::a</td>
|
||
<td>USA</td>
|
||
</tr>
|
||
<tr class="even">
|
||
<td><code>ns-gce.sslip.io.</code></td>
|
||
<td>104.155.144.4</td>
|
||
<td>USA</td>
|
||
</tr>
|
||
<tr class="odd">
|
||
<td><code>ns-azure.sslip.io.</code></td>
|
||
<td>52.187.42.158</td>
|
||
<td>Singapore</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p>Let’s test it from the command line using <code>dig</code>:</p>
|
||
<pre><code>dig @ns-gce.sslip.io. 169-254-169-254.xip.example.com +short</code></pre>
|
||
<p>Yields, hopefully: <sup><a href="#timeout" class="alert-link">[connection timed out]</a></sup></p>
|
||
<pre><code>169.254.169.254</code></pre>
|
||
<h3 id="server">But I Want My Own DNS Server!</h3>
|
||
<p>If you want to run your own DNS server, it's simple: you can compile from <a href=
|
||
"https://github.com/cunnie/sslip.io/tree/main/bosh-release/src/sslip.io-dns-server">source</a> or you can use one
|
||
of our <a href="https://github.com/cunnie/sslip.io/releases">pre-built binaries</a>. In the following example, we
|
||
install & run our server within a docker container:</p>
|
||
<pre>
|
||
docker run -it --rm fedora
|
||
curl -L https://github.com/cunnie/sslip.io/releases/download/2.5.2/sslip.io-dns-server-linux-amd64 -o dns-server
|
||
chmod +x dns-server
|
||
./dns-server 2> dns-server.log &
|
||
dnf install -y bind-utils
|
||
dig @localhost 127-0-0-1.sslip.io +short # returns "127.0.0.1"</pre>
|
||
<h3 id="tls">TLS</h3>
|
||
<p>You can acquire TLS certificates for your externally-accessible hosts from certificate authorities (CAs) such
|
||
as Let's Encrypt. The easiest mechanism to acquire a certificate would be to use the <a href=
|
||
"https://letsencrypt.org/docs/challenge-types/#http-01-challenge">HTTP-01 challenge</a>. It requires, at a
|
||
minimum, a web server running on your machine. The <a href="https://caddyserver.com/">Caddy</a> web server is one
|
||
of the most popular examples. For example, if you had a webserver with the IP address 52.0.56.137, you could
|
||
obtain a TLS certificate for "52.0.56.137.sslip.io", or "www.52.0.56.137.sslip.io", or
|
||
"prod.www-52-0-56-137.sslip.io".</p>
|
||
<div class="alert alert-warning" role="alert">
|
||
<b>2021-02-12 Let's Encrypt Rate Limits</b> If your request for an "sslip.io" certificate is <a href=
|
||
"https://letsencrypt.org/docs/rate-limits/">rate-limited</a>, please open a <a href=
|
||
"https://github.com/cunnie/sslip.io/issues/new/choose">GitHub issue</a> and we'll request a rate-limit
|
||
increase.
|
||
</div>
|
||
<p>If you have procured a wildcard certificate for your branded / white label / custom sslip.io-style subdomain,
|
||
you may install it on your machines for TLS-verified connections.</p>
|
||
<div class="alert alert-warning" data-role="alert">
|
||
<p>When using a TLS wildcard certificate in conjunction with your branded sslip.io style subdomain, you must
|
||
<b>use dashes not dots</b> as separators. For example, if you have the TLS certificate for
|
||
<i>*.xip.example.com</i>, you could browse to https://www-52-0-56-137.xip.example.com/ but not
|
||
https://www.52.0.56.137.xip.example.com/.</p>
|
||
</div>
|
||
<p>if you're interested in acquiring a wildcard certificate for your sslip.io domain, e.g.
|
||
"*.52-0-56-137.sslip.io", the procedure is described <a href=
|
||
"https://github.com/cunnie/sslip.io/blob/main/docs/wildcard.md">here</a>.</p>
|
||
<h3 id="experimental">Experimental Features</h3>
|
||
<p>Experimental features can change; don't depend on them.</p>
|
||
<h4 id="whatismyip">Determining Your External IP Address via DNS Lookup</h4>
|
||
<p>You can use sslip.io's DNS servers (<code>ns.sslip.io</code>) to determine your public IP address by querying
|
||
the <code>TXT</code> record of <code>ip.sslip.io</code>:</p>
|
||
<pre>
|
||
dig @ns.sslip.io txt ip.sslip.io +short # sample reply "2607:fb90:464:ae1e:ed60:29c:884c:4b52"
|
||
dig @ns.sslip.io txt ip.sslip.io +short -4 # forces IPv4 lookup; sample reply "172.58.35.231"
|
||
dig @ns.sslip.io txt ip.sslip.io +short -6 # forces IPv6 lookup; sample reply "2607:fb90:464:ae1e:ed60:29c:884c:4b52"</pre>
|
||
<div class="alert alert-warning" role="alert">
|
||
When querying for your IP address, always <b>include the sslip.io nameserver</b> (e.g. <i>@ns.sslip.io</i>). If
|
||
omitted, you won't get your IP address; instead, you'll get the IP address of your upstream nameserver.
|
||
</div>
|
||
<p>This feature was inspired by Google's DNS lookup, i.e. <code>dig txt o-o.myaddr.l.google.com @8.8.8.8
|
||
+short</code>. There are also popular HTTP-based services for determining your public IP address:</p>
|
||
<ul>
|
||
<li>
|
||
<a href="http://icanhazip.com/">icanhazip.com</a> (<a href=
|
||
"https://major.io/2021/06/06/a-new-future-for-icanhazip/">backstory</a>)
|
||
</li>
|
||
<li>
|
||
<a href="http://ipify.org/">ipify.org</a>
|
||
</li>
|
||
<li>
|
||
<a href="http://ip4.me/">ip4.me</a>
|
||
</li>
|
||
<li>
|
||
<a href="http://curlmyip.org/">curlmyip.org</a>
|
||
</li>
|
||
<li>
|
||
<a href="http://ifconfig.co/">ifconfig.co</a>
|
||
</li>
|
||
<li>
|
||
<a href="http://ipinfo.io/">ipinfo.io</a> (commercial)
|
||
</li>
|
||
</ul>
|
||
<p>A big advantage of using DNS queries instead of HTTP queries is bandwidth: querying
|
||
<code>ns-aws.sslip.io</code> requires a mere 592 bytes spread over 2 packets; Querying <a href=
|
||
"https://icanhazip.com/">https://icanhazip.com/</a> requires 8692 bytes spread out over 34 packets—over 14 times
|
||
as much! Admittedly bandwidth usage is a bigger concern for the one hosting the service than the one using the
|
||
service.</p><!--
|
||
<h4 id="key-value-store"><code>k-v.io</code>: (key-value) read/write/delete TXTs</h4>
|
||
<p>We enable special behavior under the <code>k-v.io</code> domain: it can be treated as a key-value store, the
|
||
subdomain being the key, and the TXT record being the value.</p>
|
||
<p>For example, to write ("put") the value "12.0.1" to the key "macos-version" on the
|
||
<code>ns-gce.sslip.io.</code> nameserver, you'd use the following <code>dig</code> command:</p>
|
||
<pre><code class="lang-shell">dig @ns-gce.sslip.io. txt put.12.0.1.macos-version.k-v.io</code>.
|
||
</pre>
|
||
<p>To read ("get") the value back, you'd write the following <code>dig</code> command:</p>
|
||
<pre><code class="lang-shell">dig @ns-gce.sslip.io. txt get.macos-version.k-v.io.</code>
|
||
</pre>
|
||
<p>Since "get" is the default behavior, you don't need to include it in the domain name:</p>
|
||
<pre><code class="lang-shell">dig @ns-gce.sslip.io. txt macos-version.k-v.io.</code>
|
||
</pre>
|
||
<p>Finally, when you're done with the key-value, you can "delete" it:</p>
|
||
<pre><code class="lang-shell">dig @ns-gce.sslip.io. txt delete.macos-version.k-v.io.
|
||
</code></pre>
|
||
<p><code class="lang-shell">Notes:</code></p>
|
||
<ul>
|
||
<li>Keys are case-insensitive (to accommodate DNS convention). In other words,
|
||
<code>KEY.k-v.io</code> and <code>key.k-v.io</code> return the same TXT record.</code></li>
|
||
<li>Values are case-sensitive. <code>put.CamelCase.style.k-v.io</code> sets the TXT record to "CamelCase".</li>
|
||
<li><code>put</code> requests will return the TXT record being put; i.e. <code>put.hello.world.k-v.io</code>
|
||
returns one TXT record of one string, <code>hello</code>.</li>
|
||
<li><code>delete</code> requests will return the TXT record being deleted; i.e.
|
||
<code>delete.world.k-v.io</code> returns one TXT record of one string, <code>hello</code>. If the TXT record
|
||
does not exist, no TXT records will be returned.</li>
|
||
<li>Values are limited to 63 bytes to mitigate using the sslip.io servers in a <a href=
|
||
"https://us-cert.cisa.gov/ncas/alerts/TA13-088A">DNS amplification attack</a>.
|
||
</li>
|
||
<li>Values are not persistent: if the server is restarted, all values disappear. Poof.</li>
|
||
<li>Values are not consistent. If a value is set in <code>ns-aws.sslip.io</code>, it does not propagate to
|
||
<code>ns-gce.sslip.io</code> nor <code>ns-azure.sslip.io</code>.</li>
|
||
</ul>
|
||
-->
|
||
<h4 id="version">Determining The Server Version of Software</h4>You can determine the server version of the
|
||
sslip.io software by querying the TXT record of <code>version.status.sslip.io</code>:
|
||
<pre>
|
||
dig @ns-gce.nono.io version.status.sslip.io txt +short
|
||
"2.4.1"
|
||
"2022/01/20-08:11:07-0800"
|
||
"14ef9a0"
|
||
</pre>
|
||
<p>The first number, ("2.4.1"), is the version of the sslip.io DNS software, and is most relevant. The other two
|
||
numbers are the date compiled and the most recent git hash, but those values can differ across servers due to the
|
||
manner in which the software is deployed.</p>
|
||
<h4 id="metrics">Server Metrics</h4>You can retrieve metrics from a given server by querying the TXT records of
|
||
<code>metrics.status.sslip.io</code>
|
||
<pre>
|
||
dig @ns-aws.sslip.io metrics.status.sslip.io txt +short
|
||
"Uptime (seconds): 13486"
|
||
"Key-value store: etcd"
|
||
"Blocklist: 2022-02-26 10:54:21-08 2,1"
|
||
"Queries: 550488"
|
||
"Queries/second: 40.8"
|
||
"AnsQueries: 149974"
|
||
"AnsQueries/second: 11.1"
|
||
"AnsA: 113520"
|
||
"AnsAAAA: 7993"
|
||
"Source IP TXT: 12"
|
||
"Version TXT: 5"
|
||
"DNS-01 challenge: 39"
|
||
</pre>
|
||
<h5>Explanation of Metrics</h5>
|
||
<dl>
|
||
<dt>Uptime</dt>
|
||
<dd>The time since the DNS server has been started, in seconds</dd>
|
||
<dt>Key-value store</dt>
|
||
<dd>This can be one of two values: "builtin" and "etcd". "builtin" means any changes to key/value are limited
|
||
to that specific DNS server. "etcd" means changes are propagated to all servers whose key-value store is
|
||
"etcd"</dd>
|
||
<dt>Blocklist</dt>
|
||
<dd>
|
||
The first value ("2022-02-26 10:54:21-08") is the date the blocklist was last downloaded. The following two
|
||
numbers are the number of string matches that are blocked (e.g. "raiffeisen" is a string that is blocked if
|
||
it appears in the queried hostname) and the number of CIDR matches that are blocked (e.g. "43.134.66.67/24"
|
||
is blocked). The blocklist can be found <a href=
|
||
"https://github.com/cunnie/sslip.io/blob/main/etc/blocklist.txt">here</a>
|
||
</dd>
|
||
<dt>Queries</dt>
|
||
<dd>The raw number of DNS queries that the server has responded to since starting operation</dd>
|
||
<dt>Queries/second</dt>
|
||
<dd>The raw number of DNS queries that the server has responded to since starting operation divided by the
|
||
number of seconds</dd>
|
||
<dt>AnsQueries</dt>
|
||
<dd>The number of queries we responded to with at least one record in the answer section. Note that the number
|
||
of answered queries is typically a third or fourth the size of the overall queries. This is normal. One reason
|
||
for this disparity is that often both the IPv4 (A) and IPv6 (AAAA) records will be checked, but only one reply
|
||
will have a record in the answer section . For example, browsing to "127.0.0.1.sslip.io" generates two lookups,
|
||
one with an answer (IPv4), and one without (IPv6). Another reason is that lookups follow a chain, e.g. looking
|
||
up "127.0.0.1.sslip.io" may generate up to four queries for A records ("1.sslip.io", "0.1.sslip.io",
|
||
"0.0.1.sslip.io" and "127.0.0.1.sslip.io"), only the last of which returns a record in the answer section.
|
||
Pro-tip: if you want to shave milliseconds off name resolution, use dashes not dots in your hostname (e.g.
|
||
"10-9-9-30.sslip.io" instead of "10.9.9.30.sslip.io")</dd>
|
||
<dt>AnsQueries/second</dt>
|
||
<dd>The raw number of DNS queries that the server has responded to with at least one record in the answer
|
||
section since starting operation divided by the number of seconds</dd>
|
||
<dt>AnsA</dt>
|
||
<dd>The number of responses which included an A (IPv4) record since starting operation (e.g. "dig
|
||
127.0.0.1.sslip.io")</dd>
|
||
<dt>AnsAAAA</dt>
|
||
<dd>The number of responses which included an AAAA (IPv6) record since starting operation (e.g. "dig
|
||
--1.sslip.io aaaa")</dd>
|
||
<dt>Source IP TXT</dt>
|
||
<dd>The number of responses which included a TXT record of the querier's IP address since starting operation
|
||
(e.g. "dig @ns.sslip.io ip.sslip.io txt")</dd>
|
||
<dt>Version TXT</dt>
|
||
<dd>The number of responses which included a TXT record of the DNS's servers version since starting operation
|
||
(e.g. "dig @ns-azure.sslip.io version.status.sslip.io txt")</dd>
|
||
<dt>DNS-01 Challenge</dt>
|
||
<dd>The number of responses which included a delegation of the NS (nameserver). This lookup is used for
|
||
generating wildcard certificates from Let's Encrypt. Technically this is not a "successful" query in that we
|
||
don't return a record in the ANSWER section, but we do return an NS record in the AUTHORITY section. (e.g. "dig
|
||
@ns-gce.sslip.io _acme-challenge.192.168.0.1.sslip.io. soa")</dd>
|
||
</dl>
|
||
<h3 id="related">Related Services</h3>
|
||
<ul>
|
||
<li>
|
||
<a href="http://xip.io/">xip.io</a>: the inspiration for sslip.io. Sadly, this appears to be no longer
|
||
maintained after <a href="https://twitter.com/sstephenson/status/1388146129284603906">Sam Stephenson left
|
||
Basecamp</a>.
|
||
</li>
|
||
<li>
|
||
<a href="http://nip.io">nip.io</a>: similar to xip.io, but the PowerDNS backend is written in elegant Python
|
||
</li>
|
||
<li>
|
||
<a href="https://github.com/Corollarium/localtls">localtls</a>: A DNS server + webserver to provide TLS to on
|
||
local addresses.
|
||
</li>
|
||
</ul>
|
||
<hr>
|
||
<h4 id="footnotes">Footnotes</h4>
|
||
<p><a id="status"><sup>[Status]</sup></a> A status of “build failing” rarely means the system is failing. It’s
|
||
more often an indication that when the servers were last checked (currently every six hours), the CI (continuous
|
||
integration) <a href="https://ci.nono.io/teams/main/pipelines/sslip.io">server</a> had difficulty reaching one of
|
||
the three sslip.io nameservers. That’s normal. <sup><a href="#timeout" class="alert-link">[connection timed
|
||
out]</a></sup></p>
|
||
<p><a id="timeout"><sup>[connection timed out]</sup></a></p>
|
||
<p>DNS runs over <a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol">UDP</a> which has no guaranteed
|
||
delivery, and it’s not uncommon for the packets to get lost in transmission. DNS clients are programmed to
|
||
seamlessly query a different server when that happens. That’s why DNS, by fiat, requires at least two nameservers
|
||
(for redundancy). From <a href="https://tools.ietf.org/html/rfc1034">IETF (Internet Engineering Task Force) RFC
|
||
(Request for Comment) 1034</a>:</p>
|
||
<blockquote>
|
||
<p>A given zone will be available from several name servers to insure its availability in spite of host or
|
||
communication link failure. By administrative fiat, we require every zone to be available on at least two
|
||
servers, and many zones have more redundancy than that.</p>
|
||
</blockquote>
|
||
</div>
|
||
</div><!-- /.container -->
|
||
<!--
|
||
Bootstrap core JavaScript ================================================== -->
|
||
<!--
|
||
Placed at the end of the document so the pages load faster -->
|
||
<!-- jQuery
|
||
(necessary for Bootstrap's JavaScript plugins) -->
|
||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
|
||
<!-- Latest compiled and minified JavaScript -->
|
||
|
||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
|
||
<!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
|
||
|
||
<script src=
|
||
"https://raw.githubusercontent.com/twbs/bootstrap/master/docs/assets/js/ie10-viewport-bug-workaround.js"></script>
|
||
<!-- Google Analytics -->
|
||
|
||
<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', 'UA-43107212-2', 'auto');
|
||
ga('send', 'pageview');
|
||
</script>
|
||
</body>
|
||
</html>
|