mirror of
https://codeberg.org/slatian/service.echoip-slatecave.git
synced 2025-07-17 14:33:27 +02:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
f9753ccbfc | |||
a9512d7d4d | |||
6a57780490 | |||
51f27be997 | |||
554c788488 | |||
6d7e5ac18f | |||
3bcf8fde39 |
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -372,6 +372,7 @@ dependencies = [
|
||||
"idna 0.3.0",
|
||||
"lazy_static",
|
||||
"maxminddb",
|
||||
"parking_lot",
|
||||
"regex",
|
||||
"serde",
|
||||
"tera",
|
||||
|
@ -13,6 +13,7 @@ clap = { version = "4", features = ["derive"] }
|
||||
governor = "0.5"
|
||||
idna = "0.3"
|
||||
lazy_static = "1.4.0"
|
||||
parking_lot = "0.12"
|
||||
regex = "1.7"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
|
@ -44,6 +44,12 @@ The default templates should make use of everything exposed to the templating pa
|
||||
|
||||
The templates are covered by the AGPL as well, please share them with your users if you modified them.
|
||||
|
||||
### GeoLite2 database
|
||||
|
||||
For geolocation to work you need a MaxMind format database, for full functionality you need the GeoLite2-ASN and GeoLite2-City databses. Unfortunately you have to sign up with [MaxMind](https://maxmind.com) to obtain them. Once you have a license key there is a helper script in [contrib/maxmind-download.sh](contrib/maxmind-download.sh) that helps you with keeping the databse updated.
|
||||
|
||||
Since v1.0 echoip-slatecave reloads the databses when it rececieves a `USR1` signal.
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Information disclosure
|
||||
@ -59,7 +65,7 @@ For a public service you should use a reverse proxy like Caddy, apache2 or nginx
|
||||
### Denail of Service
|
||||
|
||||
`echoip-slatecave` has some simle ratelimiting built in (see the `[ratelimit]` section in the configuration file) this should help you with too frequest automated requests causung high load.
|
||||
The default configuration is pretty liberal so that the average human probably won't notice the rate limit, but a misbehavin bot will be limited to one request every 3 seconds after 15 requests.
|
||||
The default configuration is pretty liberal so that the average human probably won't notice the rate limit, but a misbehavingig bot will be limited to one request every 3 seconds after 15 requests.
|
||||
|
||||
## License
|
||||
|
||||
|
174
contrib/maxmind-download.sh
Normal file
174
contrib/maxmind-download.sh
Normal file
@ -0,0 +1,174 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Settings variables go here
|
||||
GEOIP_LICENSE_KEY="$GEOIP_LICENSE_KEY"
|
||||
PRODUCTS=()
|
||||
DESTINATION_DIRECTORY="."
|
||||
DOWNLOAD_LOCATION=""
|
||||
COLOR_OUTPUT=""
|
||||
[ -t 1 ] && COLOR_OUTPUT="y"
|
||||
|
||||
msg() {
|
||||
COLOR=""
|
||||
COLOR_RST=""
|
||||
if [ -n "$COLOR_OUTPUT" ] ; then
|
||||
COLOR_RST="\e[00m"
|
||||
case "$2" in
|
||||
error|init_error) COLOR="\e[01;31m" ;;
|
||||
success) COLOR="\e[32m" ;;
|
||||
*) ;;
|
||||
esac
|
||||
fi
|
||||
printf "$COLOR%s$COLOR_RST\n" "$1" >&2
|
||||
}
|
||||
|
||||
show_help() {
|
||||
cat <<EOF
|
||||
Usage: maxmind-download.sh [OPTIONS]...
|
||||
|
||||
OPTIONS
|
||||
--license-key <key>
|
||||
Set the licencse key that is unfortunately
|
||||
needed for a successful download.
|
||||
--product <id>
|
||||
Which product to download
|
||||
maxmind calls this the EditionID
|
||||
--GeoLite2-mmdb-all
|
||||
Selects all the GeoLite2 Products in mmdb
|
||||
format, hoefully saves some headaces.
|
||||
Will download:
|
||||
* GeoLite2-ASN
|
||||
* GeoLite2-City
|
||||
* GeoLite2-Country
|
||||
--to <destination>
|
||||
Directory to place the downloded files in.
|
||||
Filename will be <product>.(mmdb|csv)
|
||||
--download-to <destination>
|
||||
Directory to download to.
|
||||
If specified, the files in the --to directory
|
||||
will only be replaced if the download was successful.
|
||||
--color
|
||||
--no-color Explicitly enable or disable colored output.
|
||||
--help Show this help message
|
||||
|
||||
ENVOIRNMENT
|
||||
GEOIP_LICENSE_KEY can be used to set the licencse key.
|
||||
|
||||
EXIT CODES
|
||||
1 Invalid paramters or filesystem envoirnment
|
||||
2 Download failed
|
||||
3 Expected file not found in download
|
||||
4 Failed to extract download
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--license-key) GEOIP_LICENSE_KEY="$2"; shift 2;;
|
||||
--product) PRODUCTS+=("$2"); shift 2;;
|
||||
--GeoLite2-mmdb-all)
|
||||
PRODUCTS+=("GeoLite2-ASN")
|
||||
PRODUCTS+=("GeoLite2-City")
|
||||
PRODUCTS+=("GeoLite2-Country")
|
||||
shift 1;;
|
||||
--to) DESTINATION_DIRECTORY="$2"; shift 2;;
|
||||
--download-to) DOWNLOAD_LOCATION="$2"; shift 2;;
|
||||
--color) COLOR_OUTPUT="y"; shift 1;;
|
||||
--no-color) COLOR_OUTPUT=""; shift 1;;
|
||||
|
||||
--help) show_help; exit 0;;
|
||||
*) printf "Unknown option: %s\n" "$1"; exit 1;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z "$GEOIP_LICENSE_KEY" ] ; then
|
||||
msg "No License Key specified, the download won't work this way." init_error
|
||||
exit 1
|
||||
fi
|
||||
|
||||
[ -n "$DOWNLOAD_LOCATION" ] || DOWNLOAD_LOCATION="$DESTINATION_DIRECTORY"
|
||||
|
||||
if [ -d "$DESTINATION_DIRECTORY" ] || mkdir -p "$DESTINATION_DIRECTORY" ; then
|
||||
true
|
||||
else
|
||||
msg "Destination is not a directory and can't be created!" init_error
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -d "$DOWNLOAD_LOCATION" ] || mkdir -p "$DOWNLOAD_LOCATION" ; then
|
||||
true
|
||||
else
|
||||
msg "Dowload location is not a directory and can't be created!" init_error
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "${#PRODUCTS[@]}" -eq "0" ] ; then
|
||||
msg "No products specified, nothing to do." init_error
|
||||
exit 0
|
||||
fi
|
||||
|
||||
get_product_file_ext() {
|
||||
if printf "%s" "$1" | grep -q 'CSV$' ; then
|
||||
echo csv
|
||||
else
|
||||
echo mmdb
|
||||
fi
|
||||
}
|
||||
|
||||
# PrductID,DOWNLOAD_LOCATION
|
||||
download_maxmind_db() {
|
||||
msg "Downloading Database $1 …" progess
|
||||
# the path to download to
|
||||
dl="$2/$1.tar.gz"
|
||||
curl -fsSL -m 40 "https://download.maxmind.com/app/geoip_download?edition_id=$1&license_key=$GEOIP_LICENSE_KEY&suffix=tar.gz" > "$dl"
|
||||
if [ "_$?" != "_0" ] ; then
|
||||
msg "Databse download of $1 failed!" error
|
||||
rm "$dl"
|
||||
return 2
|
||||
fi
|
||||
EXT="$(get_product_file_ext "$1")"
|
||||
FILE_TO_EXTRACT="$(tar -tzf "$dl" | grep "/$1\.$EXT$")"
|
||||
if [ -z "$FILE_TO_EXTRACT" ] ; then
|
||||
msg "No .$EXT file found in the downloaded data!" error
|
||||
rm "$dl"
|
||||
return 3
|
||||
fi
|
||||
msg "Extracting $FILE_TO_EXTRACT from downloaded archive …" progess
|
||||
if tar -C "$2" --strip-components=1 -xzf "$dl" "$FILE_TO_EXTRACT" ; then
|
||||
msg "File extracted successfully." success
|
||||
rm "$dl"
|
||||
return 0
|
||||
else
|
||||
msg "File extraction failed!" error
|
||||
rm "$dl"
|
||||
return 4
|
||||
fi
|
||||
}
|
||||
|
||||
EXIT_CODE=""
|
||||
MSG_OUTPUT_TO_LOG="y"
|
||||
for product in "${PRODUCTS[@]}" ; do
|
||||
download_maxmind_db "$product" "$DOWNLOAD_LOCATION"
|
||||
RETCODE="$?"
|
||||
|
||||
if [ "_$RETCODE" = "_0" ] ; then
|
||||
filename="$product.$(get_product_file_ext "$product")"
|
||||
if [ "_$DOWNLOAD_LOCATION" != "_$DESTINATION_DIRECTORY" ] ; then
|
||||
msg "Moving destination file …" progess
|
||||
if [ -e "$DESTINATION_DIRECTORY/$filename" ] ; then
|
||||
[ -e "$DESTINATION_DIRECTORY/$filename.bak" ] && rm "$DESTINATION_DIRECTORY/$filename.bak"
|
||||
mv "$DESTINATION_DIRECTORY/$filename" "$DESTINATION_DIRECTORY/$filename.bak"
|
||||
fi
|
||||
if mv "$DOWNLOAD_LOCATION/$filename" "$DESTINATION_DIRECTORY/$filename" ; then
|
||||
msg "File $filename installed successfully." success
|
||||
else
|
||||
msg "Failed to install $filename!" error
|
||||
fi
|
||||
fi
|
||||
else
|
||||
[ -n "$EXIT_CODE" ] && [ "$EXIT_CODE" -lt "$RETCODE" ] || export EXIT_CODE="$RETCODE"
|
||||
fi
|
||||
done
|
||||
|
||||
exit $EXIT_CODE
|
35
src/geoip.rs
35
src/geoip.rs
@ -6,6 +6,8 @@
|
||||
use maxminddb;
|
||||
use maxminddb::geoip2;
|
||||
|
||||
use parking_lot::RwLock;
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::net::IpAddr;
|
||||
use std::path::Path;
|
||||
@ -47,8 +49,9 @@ pub struct AsnResult {
|
||||
}
|
||||
|
||||
pub struct MMDBCarrier {
|
||||
pub mmdb: Option<maxminddb::Reader<Vec<u8>>>,
|
||||
pub mmdb: RwLock<Option<maxminddb::Reader<Vec<u8>>>>,
|
||||
pub name: String,
|
||||
pub path: Option<String>,
|
||||
}
|
||||
|
||||
pub trait QueryLocation {
|
||||
@ -122,7 +125,8 @@ pub fn geoip2_subdivision_to_named_location(item: geoip2::city::Subdivision, lan
|
||||
|
||||
impl QueryAsn for MMDBCarrier {
|
||||
fn query_asn_for_ip(&self, address: &IpAddr) -> Option<AsnResult> {
|
||||
match &self.mmdb {
|
||||
let mmdb = self.mmdb.read();
|
||||
match &*mmdb {
|
||||
Some(mmdb) => {
|
||||
match mmdb.lookup::<geoip2::Asn>(*address) {
|
||||
Ok(res) => {
|
||||
@ -144,7 +148,8 @@ impl QueryAsn for MMDBCarrier {
|
||||
|
||||
impl QueryLocation for MMDBCarrier {
|
||||
fn query_location_for_ip(&self, address: &IpAddr, languages: &Vec<&String>) -> Option<LocationResult> {
|
||||
match &self.mmdb {
|
||||
let mmdb = self.mmdb.read();
|
||||
match &*mmdb {
|
||||
Some(mmdb) => {
|
||||
match mmdb.lookup::<geoip2::City>(*address) {
|
||||
Ok(res) => {
|
||||
@ -210,22 +215,38 @@ impl QueryLocation for MMDBCarrier {
|
||||
}
|
||||
|
||||
impl MMDBCarrier {
|
||||
pub fn load_database_from_path(&mut self, path: &Path) -> Result<(),maxminddb::MaxMindDBError> {
|
||||
pub fn new(name: String, path: Option<String>) -> MMDBCarrier {
|
||||
MMDBCarrier {
|
||||
mmdb: RwLock::new(None),
|
||||
name: name,
|
||||
path: path,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reload_database(&self) -> Result<(),maxminddb::MaxMindDBError> {
|
||||
match &self.path {
|
||||
Some(path) => self.load_database_from_path(Path::new(&path)),
|
||||
None => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_database_from_path(&self, path: &Path) -> Result<(),maxminddb::MaxMindDBError> {
|
||||
let mut mmdb = self.mmdb.write();
|
||||
println!("Loading {} from '{}' ...", &self.name, path.display());
|
||||
match maxminddb::Reader::open_readfile(path) {
|
||||
Ok(reader) => {
|
||||
let wording = if self.mmdb.is_some() {
|
||||
let wording = if mmdb.is_some() {
|
||||
"Replaced old"
|
||||
} else {
|
||||
"Loaded new"
|
||||
};
|
||||
self.mmdb = Some(reader);
|
||||
*mmdb = Some(reader);
|
||||
println!("{} {} with new one.", wording, &self.name);
|
||||
Ok(())
|
||||
},
|
||||
Err(e) => {
|
||||
println!("Error while reading {}: {}", &self.name, &e);
|
||||
if self.mmdb.is_some() {
|
||||
if mmdb.is_some() {
|
||||
println!("Not replacing old database.");
|
||||
}
|
||||
Err(e)
|
||||
|
55
src/main.rs
55
src/main.rs
@ -27,10 +27,15 @@ use trust_dns_resolver::{
|
||||
// config::ResolverConfig,
|
||||
};
|
||||
|
||||
use tokio::signal::unix::{
|
||||
signal,
|
||||
SignalKind,
|
||||
};
|
||||
use tokio::task;
|
||||
|
||||
use std::fs;
|
||||
use std::net::IpAddr;
|
||||
use std::sync::Arc;
|
||||
use std::path::Path;
|
||||
|
||||
mod config;
|
||||
mod geoip;
|
||||
@ -205,23 +210,19 @@ async fn main() {
|
||||
|
||||
// Initalize GeoIP Database
|
||||
|
||||
let mut asn_db = geoip::MMDBCarrier {
|
||||
mmdb: None,
|
||||
name: "GeoIP ASN Database".to_string(),
|
||||
};
|
||||
match &config.geoip.asn_database {
|
||||
Some(path) => { asn_db.load_database_from_path(Path::new(&path)).ok(); },
|
||||
None => {},
|
||||
}
|
||||
let asn_db = geoip::MMDBCarrier::new(
|
||||
"GeoIP ASN Database".to_string(),
|
||||
config.geoip.asn_database.clone()
|
||||
);
|
||||
|
||||
let mut location_db = geoip::MMDBCarrier {
|
||||
mmdb: None,
|
||||
name: "GeoIP Location Database".to_string(),
|
||||
};
|
||||
match &config.geoip.location_database {
|
||||
Some(path) => { location_db.load_database_from_path(Path::new(&path)).ok(); },
|
||||
None => {},
|
||||
}
|
||||
asn_db.reload_database().ok();
|
||||
|
||||
let location_db = geoip::MMDBCarrier::new(
|
||||
"GeoIP Location Database".to_string(),
|
||||
config.geoip.location_database.clone()
|
||||
);
|
||||
|
||||
location_db.reload_database().ok();
|
||||
|
||||
// Initalize DNS resolver with os defaults
|
||||
println!("Initalizing dns resolver ...");
|
||||
@ -250,6 +251,26 @@ async fn main() {
|
||||
config: config.clone(),
|
||||
});
|
||||
|
||||
let signal_usr1_handlers_state = shared_state.clone();
|
||||
|
||||
task::spawn(async move {
|
||||
println!("Trying to register USR1 signal for reloading geoip databases");
|
||||
let mut signal_stream = match signal(SignalKind::user_defined1()) {
|
||||
Ok(signal_stream) => signal_stream,
|
||||
Err(e) => {
|
||||
println!("Error while registring signal handler: {e}");
|
||||
println!("Continuing without ...");
|
||||
return;
|
||||
}
|
||||
};
|
||||
loop {
|
||||
if None == signal_stream.recv().await { return; }
|
||||
println!("Received signal USR1, reloading geoip databses!");
|
||||
signal_usr1_handlers_state.location_db.reload_database().ok();
|
||||
signal_usr1_handlers_state.asn_db.reload_database().ok();
|
||||
}
|
||||
});
|
||||
|
||||
// Initalize axum server
|
||||
let app = Router::new()
|
||||
.route("/", get(handle_default_route))
|
||||
|
@ -18,6 +18,8 @@ use trust_dns_resolver::{
|
||||
TokioAsyncResolver,
|
||||
};
|
||||
|
||||
use tokio::join;
|
||||
|
||||
use std::net::IpAddr;
|
||||
|
||||
|
||||
@ -211,34 +213,50 @@ pub async fn lookup(
|
||||
name: &String,
|
||||
do_full_lookup: bool,
|
||||
) -> DnsLookupResult {
|
||||
let ipv4_lookup_res = resolver.lookup(name, RecordType::A);
|
||||
let ipv6_lookup_res = resolver.lookup(name, RecordType::AAAA);
|
||||
let cname_lookup_res = resolver.lookup(name, RecordType::CNAME);
|
||||
let aname_lookup_res = resolver.lookup(name, RecordType::ANAME);
|
||||
let (
|
||||
ipv4_lookup_res,
|
||||
ipv6_lookup_res,
|
||||
cname_lookup_res,
|
||||
aname_lookup_res
|
||||
) = join!(
|
||||
resolver.lookup(name, RecordType::A),
|
||||
resolver.lookup(name, RecordType::AAAA),
|
||||
resolver.lookup(name, RecordType::CNAME),
|
||||
resolver.lookup(name, RecordType::ANAME),
|
||||
);
|
||||
|
||||
// initlize an empty lookup result
|
||||
let mut dig_result: DnsLookupResult = Default::default();
|
||||
|
||||
integrate_lookup_result(&mut dig_result, ipv4_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, ipv6_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, cname_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, aname_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, ipv4_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, ipv6_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, cname_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, aname_lookup_res);
|
||||
|
||||
//Don't do an extented lookup if the domain seemingly doesn't exist
|
||||
if do_full_lookup && !dig_result.nxdomain {
|
||||
let mx_lookup_res = resolver.lookup(name, RecordType::MX);
|
||||
let ns_lookup_res = resolver.lookup(name, RecordType::NS);
|
||||
let soa_lookup_res = resolver.lookup(name, RecordType::SOA);
|
||||
let caa_lookup_res = resolver.lookup(name, RecordType::CAA);
|
||||
let srv_lookup_res = resolver.lookup(name, RecordType::SRV);
|
||||
let txt_lookup_res = resolver.lookup(name, RecordType::TXT);
|
||||
let (
|
||||
mx_lookup_res,
|
||||
ns_lookup_res,
|
||||
soa_lookup_res,
|
||||
caa_lookup_res,
|
||||
srv_lookup_res,
|
||||
txt_lookup_res
|
||||
) = join!(
|
||||
resolver.lookup(name, RecordType::MX),
|
||||
resolver.lookup(name, RecordType::NS),
|
||||
resolver.lookup(name, RecordType::SOA),
|
||||
resolver.lookup(name, RecordType::CAA),
|
||||
resolver.lookup(name, RecordType::SRV),
|
||||
resolver.lookup(name, RecordType::TXT),
|
||||
);
|
||||
|
||||
integrate_lookup_result(&mut dig_result, mx_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, ns_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, soa_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, caa_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, srv_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, txt_lookup_res.await);
|
||||
integrate_lookup_result(&mut dig_result, mx_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, ns_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, soa_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, caa_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, srv_lookup_res);
|
||||
integrate_lookup_result(&mut dig_result, txt_lookup_res);
|
||||
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if r.cname %}
|
||||
<p>This domain has a cname set, this means its contents are full replaced by the linked record.</p>
|
||||
<p>This domain has a <code>CNAME</code> set, this means its contents are full replaced by the linked record.</p>
|
||||
|
||||
<p class="button-paragraph">{{ helper::dig(extra=extra, name=r.cname[0]) }}</p>
|
||||
|
||||
@ -194,7 +194,7 @@
|
||||
<h2>Programatic Lookup</h2>
|
||||
<p>If you want to look up this information in another program the short answer is <b>don't, look up the names using your local DNS!</b></p>
|
||||
<p>On most systems on the commandline you have commands like <code>host</code> and <code>dig</code> even when not present you can probably use <code>ping</code> as a workaround as it resolves the name and gives you the IP-Address it is pinging.</p>
|
||||
<h3>Why queryting this service is still useful</h3>
|
||||
<h3>Why querying this service is still useful</h3>
|
||||
<p>This service most probably doesn't share its cache with your local resolver, this way you have a way to see if your DNS-change had the effect it should have.</p>
|
||||
<p>It may also be useful for debugging other dns problems or to get around a local resolver that is lying to you because your ISP is a <i>something</i>.</p>
|
||||
<h3>How?</h3>
|
||||
|
@ -60,7 +60,7 @@
|
||||
{% endif %}
|
||||
{% if r.location.coordinates %}
|
||||
<dt>Coordinates</dt>
|
||||
<dd><a href="{{ links::map_link(lat=r.location.coordinates.lat, lon=r.location.coordinates.lon)}}">lat: {{r.location.coordinates.lat}}, lon: {{r.location.coordinates.lon}}</a></dd>
|
||||
<dd><a target="_blank" href="{{ links::map_link(lat=r.location.coordinates.lat, lon=r.location.coordinates.lon)}}">lat: {{r.location.coordinates.lat}}, lon: {{r.location.coordinates.lon}}</a></dd>
|
||||
{% endif %}
|
||||
</dl>
|
||||
<!--We have to put that there to comply with maxminds licensing-->
|
||||
|
@ -3,6 +3,7 @@
|
||||
<ul class="link-list">
|
||||
<li><a target="_blank" href="https://apps.db.ripe.net/db-web-ui/query?bflag=true&dflag=false&rflag=true&searchtext={{ address }}&source=RIPE">… in the RIPE Database</a></li>
|
||||
<li><a target="_blank" href="https://apps.db.ripe.net/db-web-ui/query?bflag=true&dflag=false&rflag=true&searchtext={{ address }}&source=GRS">… in the RIPE Global Resources Service</a></li>
|
||||
<li><a target="_blank" href="https://client.rdap.org/?type=ip&object={{ address }}">… on client.rdap.org <small>(a modern whois, make sure to allow xhr to 3rd parties)</small></a></li>
|
||||
<li><a target="_blank" href="https://www.shodan.io/host/{{ address }}">… on shodan.io <small>(limited querys per day, wants an account)</small></a></li>
|
||||
<li><a target="_blank" href="https://search.censys.io/search?resource=hosts&sort=RELEVANCE&per_page=25&virtual_hosts=EXCLUDE&q=ip%3D{{ address }}">… on search.censys.io <small>(10 querys per day, wants an account)</small></a></li>
|
||||
{% if not address is matching(":") %}
|
||||
@ -18,6 +19,9 @@
|
||||
<li><a target="_blank" href="https://www.shodan.io/domain/{{ name }}">… on shodan.io <small>(limited querys per day, wants an account)</small></a></li>
|
||||
<li><a target="_blank" href="https://search.censys.io/search?resource=hosts&sort=RELEVANCE&per_page=25&virtual_hosts=EXCLUDE&q={{ name }}">… on search.censys.io <small>(10 querys per day, wants an account)</small></a></li>
|
||||
<li><a target="_blank" href="https://www.virustotal.com/gui/domain/{{ name }}">… on virustotal.com</a></li>
|
||||
<li><a target="_blank" href="https://observatory.mozilla.org/analyze/{{ name }}">… on the Mozilla Observatory (http and tls checks)</a></li>
|
||||
<li><a target="_blank" href="https://internet.nl/site/{{ name }}">… on the Internet.nl Website test</a></li>
|
||||
<li><a target="_blank" href="https://client.rdap.org/?type=domain&object={{ name }}">… on client.rdap.org <small>(a modern whois, make sure to allow xhr to 3rd parties)</small></a></li>
|
||||
</ul>
|
||||
{% endmacro domain_name_links %}
|
||||
|
||||
@ -27,6 +31,7 @@
|
||||
<li><a target="_blank" href="https://bgp.he.net/AS{{asn}}">… on Hurricane Electric BGP Toolkit</a></li>
|
||||
<li><a target="_blank" href="https://radar.qrator.net/as{{asn}}">… on radar.qrator.net (BGP Tool)</a></li>
|
||||
<li><a target="_blank" href="https://search.censys.io/search?resource=hosts&sort=RELEVANCE&per_page=25&virtual_hosts=EXCLUDE&q=autonomous_system.asn%3D{{asn}}">… on search.censys.io <small>(10 querys per day, wants an account)</small></a></li>
|
||||
<li><a target="_blank" href="https://client.rdap.org/?type=autnum&object={{ asn }}">… on client.rdap.org <small>(a modern whois, make sure to allow xhr to 3rd parties)</small></a></li>
|
||||
<li><a target="_blank" href="https://query.wikidata.org/#%23Select%20Wikipedia%20articles%20that%20belong%20to%20a%20given%20asn%0ASELECT%20DISTINCT%20%3Fitem%20%3Fwebsite%20%3FitemLabel%20%3FitemDescription%20%3Flang%20%3Farticle%20WHERE%20%7B%0A%20%20VALUES%20%3Fasn%20%7B%0A%20%20%20%20%22{{ asn }}%22%0A%20%20%7D%0A%20%20%3Fasn%20%5Ewdt%3AP3797%20%3Fitem.%0A%20%20OPTIONAL%20%7B%20%3Fitem%20wdt%3AP856%20%3Fwebsite.%20%7D%0A%20%20OPTIONAL%20%7B%0A%20%20%20%20%3Fitem%20%5Eschema%3Aabout%20%3Farticle.%0A%20%20%20%20%3Farticle%20schema%3AisPartOf%20_%3Ab64.%0A%20%20%20%20_%3Ab64%20wikibase%3AwikiGroup%20%22wikipedia%22.%0A%20%20%20%20%3Farticle%20schema%3AinLanguage%20%3Flang%3B%0A%20%20%20%20%20%20schema%3Aname%20%3Farticlename.%0A%20%20%20%20FILTER(((%3Flang%20%3D%20%22%5BAUTO_LANGUAGE%5D%22)%20%7C%7C%20(%3Flang%20%3D%20%22en%22))%20%7C%7C%20(%3Flang%20%3D%20%22de%22))%0A%20%20%7D%0A%20%20SERVICE%20wikibase%3Alabel%20%7B%0A%20%20%20%20bd%3AserviceParam%20wikibase%3Alanguage%20%22%5BAUTO_LANGUAGE%5D%2Cen%22.%0A%20%20%20%20%3Fitem%20rdfs%3Alabel%20%3FitemLabel%3B%0A%20%20%20%20%20%20schema%3Adescription%20%3FitemDescription.%0A%20%20%7D%0A%7D%0AORDER%20BY%20(UCASE(%3FitemLabel))">… on Wikidata and Wikipedia <small>(Press the run button in the sidebar to get results)</small></a></li>
|
||||
</ul>
|
||||
{% endmacro asn_links %}
|
||||
|
@ -1,2 +1,3 @@
|
||||
User-agent: *
|
||||
Disallow: /*?
|
||||
Disallow: /ip/
|
||||
Disallow: /dig/
|
Reference in New Issue
Block a user