add entries to hosts file based on facts - puppet

In Puppet I would like to create entries to all hosts files in a large group of servers.
256.344.987.776 6.fqn.mycompany.info my-hosts-hostname6
256.344.987.777 7.fqn.mycompany.info my-hosts-hostname7
256.344.987.778 8.fqn.mycompany.info my-hosts-hostname8
256.344.987.779 9.fqn.mycompany.info my-hosts-hostname9
256.344.987.780 10.fqn.mycompany.info my-hosts-hostname10
where the IP is taken from eth2 fact, the fqn is taken from concatting a fact hostname to domain, the short notation would be the fact: hostname.
I'm not sure how to best approach this.

It sounds like you want to glean the information from all of your hosts, collate it, and provide it to all the hosts. This is one of the classic use cases for exported resources. And of course, Puppet provides a built-in Host resource type for managing the individual entries. A minimal class that handles such a job might look like this:
class site::hosts {
# Export *this* host's entry for all machines to pick up
##host { "${hostname}.${domain}":
ensure => 'present',
ip => $ipaddress_eth2,
host_aliases => ${hostname}
}
# Apply *all* machines' hosts entries to this machine
Host<<| |>>
}
You will need to have exported resources enabled on your master for this to work. After you first put it into place, it may take a couple of cycles to stabilize, as on any given run, each host will receive only the entries provided by machines that have already received catalogs with that class in them.

Related

How to remove network addresses from a list if they are a subnet of another network

After creating a list of ipaddress/CIDR from a csv file, converting the ipaddresses to network addresses and then eliminating duplicates by creating a set from the list (python 3.7), I iterate and eliminate all subnets that are subnets_of() another subnet, keeping the summarized or supernet address. I use the ipaddress module to do this work. The problem is, if the subnet is compared to itself, it still counts as a subnet. for example,
a = ipaddress.ip_network('192.168.0.0/24')
b = ipaddress.ip_network('192.168.0.0/24')
b.subnet_of(a)
True
So I even if there is a 192.168.0.0/23 in my list, the /24 is still added because all addresses are compared to all addresses. Is there a better to handle this type of situation?
I've tried removing the the subnet from my working list so it won't be iterated over again, no luck.
No error messages. I just get a subnet included that fits within a larger subnet in my list. This leaves an entry that is unnecessary.
have you tried just removing everything after the /?

How to change the middle node location in the torrc?

I am trying to edit my torrc and make all of the nodes funnel through one country.
So far I am able to force the entry and exit nodes but don't know how to change the middle node... any ideas?
I have already tried "MiddleNodes" and "RelayNodes"
EntryNodes {us},{ca}
ExitNodes {us},{ca}
StrictNodes 1
It's possible to restrict to MiddleNodes per Tor docs: https://2019.www.torproject.org/docs/tor-manual.html.en
MiddleNodes node,node,…
A list of identity fingerprints and country
codes of nodes to use for "middle" hops in your normal circuits.
Normal circuits include all circuits except for direct connections to
directory servers. Middle hops are all hops other than exit and entry.
This is an experimental feature that is meant to be used by
researchers and developers to test new features in the Tor network
safely. Using it without care will strongly influence your anonymity.
This feature might get removed in the future. The HSLayer2Node and
HSLayer3Node options override this option for onion service circuits,
if they are set. The vanguards addon will read this option, and if
set, it will set HSLayer2Nodes and HSLayer3Nodes to nodes from this
set. The ExcludeNodes option overrides this option: any node listed in
both MiddleNodes and ExcludeNodes is treated as excluded. See the
ExcludeNodes option for more information on how to specify nodes.
Edit: See new answer by #user1652110 describing MiddleNodes option which was added in January 2019.
There is no option to do so. The closest option you can try is ExcludeNodes by using as large a list of country codes as you can come up with that doesn't include the countries you do want to use.
Also note, at the time of writing, limiting your circuits' entry and exit points to relays in the US and Canada might severely limit your performance, anonymity, and reliability since there just aren't that many high-bandwidth exits and guards in these two countries.

How to convert virtual resources to a hash

I have a resource that takes ‘hash’ as an argumnent:
nginx::resource::map { ‘verions’:
mappings => { hash of nginx upstreams here }
}
The problem is, the data for that hash is not available at the place, but all over the environment. So i came up with idea to use virtual resources at those places:
#upstream_entry { ‘name’: location => ‘location’ }
And then collect them at the place
Upstream_Entry <| |>
But that doesnt help much excepts it gathers data together. How can I convert those fake resources into a hash and feed it to nginx?
This is related to templates since all the nginx::resource::map does it creates a file with hash conents.
After several days of researching I came into a conclusion that this is, in fact, not possible.
I can, however, use concat module (with concat::fragment) to construct a configuration file from resources, by defining concat::fragment inside of them.
So that's why I came up into a pull request for nginx module that solves my particular case: I simply had to abandon the idea of using hash as "upstreams source", but rather to use Puppet resources to define them, and them collect them together with concat.

Live with Predictable Network Interface Name

I'm facing for the first time with the new name scheme of network interfaces: Predictable Network Interface Name.
My question is NOT related if this scheme is better or worse... I'm just trying to understand how to use it correcly.
Here I read:
When changing the interface naming scheme, do not forget to update all network-related configuration files and custom systemd unit files to reflect the change.
So I have to write in all the configuration files the actual interface name. In the previous scheme it was i.e. eth0 and it just means the first ethernet card, with the known caveats if there are multiple interfaces.
Now, instead, I have to write the predictable name, that is composed of some easy parts (i.e. type of the interface) and other un-predictable ones like the MAC address. As far as I understand each card will have a different name.
I admit my question might appear fool, but I don't understand how to prepare a configuration file. Let's see an example, /etc/dhcpcd.conf:
profile static_eth0
static ip_address=192.168.1.23/24
static routers=192.168.1.1
static domain_name_servers=192.168.1.1
interface eth0
fallback static_eth0
What should I put instead of eth0 in the o.s. image?
Only when I run the target machine I can retreive the actual name of the ethernet interface.
100% of my systems are headless, and I never connect a keyboard and display to them. Furthermore, if I have to send a spare part of the SBC do I need to reconfigure all?
Would you please help me to understand the correct usage?
ps. I know I can revert back to the old naming scheme... but that's not the point of my question.
See https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/
it explains how the names are assigned
Names incorporating Firmware/BIOS provided index numbers for on-board devices (example: eno1)
Names incorporating Firmware/BIOS provided PCI Express hotplug slot index numbers (example: ens1)
Names incorporating physical/geographical location of the connector of the hardware (example: enp2s0)
Names incorporating the interfaces's MAC address (example: enx78e7d1ea46da)
Classic, unpredictable kernel-native ethX naming (example: eth0)
By default, systemd v197 will now name interfaces following policy 1) if that
information from the firmware is applicable and available, falling back to 2) if
that information from the firmware is applicable and available, falling back to 3)
if applicable, falling back to 5) in all other cases. Policy 4) is not used by
default, but is available if the user chooses so.
So you could opt for a different approach, likely in your setup its easiest to take the mac, just reboot once an image that tries pxe/dhcp requests and note down the sended mac.
Another way, that may work, depending on your setup, would be interface groupings.
From "man interfaces"
auto /eth*
If the kernel knows about the interfaces with names lo, eth0 and eth1, then the above line is then interpreted as:
auto eth0 eth1
Note that there must still be valid "iface" stanzas for each matching interface. However, it is possible to combine a pattern with a mapping to a logical interface, like so:
auto /eth*=eth
iface eth inet dhcp
So maybe if you only have one interface, but can't tell where it will be assigned, you could write "auto /e*=eth" to catch all interfaces starting with e and address them inside the configuration file as "eth".

Knot Resolver: How to observe and modify a resolved answer at the right time

Goal
I would like to stitch up a GNU GPL licensed Knot Resolver module either in C or in CGO that would examine the client's query and the corresponding resolved answer with the goal of querying an external API offering a knowledge base of malware infected hostnames and ip addresses (e.g. GNU AGPL v3 IntelMQ).
If there is a match with the resolved A's (AAAA's) IP address it is to be logged, likewise a match with the queried hostname should be logged or (optionally) it could result in sending the client an IP address of a sinkhole instead of the resolved one.
Means
I studied the layers and I came to the conclusion that the phase I'm interested in is consume. I don't want to affect the resolution process, I just want to step in at the last moment and check the results and possibly modify them.
I ventured to register the a consume function
with
static knot_layer_api_t _layer = {
.consume = &consume,
};
but I'm not sure it is the right place to do the deed.
Furthermore, I also looked into module hints.c, especially its query method
and module stats.c for its _to_wire function usage.
Question(s)
Phase (Layer?)
When is the right time to step in and read/write the answer to the query before it's send to the client? Am I at the right spot in consume layer?
Answer sections
If the following attempt at getting the resolved IP address gives me the Name Server's address:
char addr_str[INET6_ADDRSTRLEN];
memset(addr_str, 0, sizeof(addr_str));
const struct sockaddr *src = &(req->answer->sections);
inet_ntop(qry->ns.addr[0].ip.sa_family, kr_inaddr(src), addr_str, sizeof(addr_str));
DEBUG_MSG(NULL, "ADDR: %s\n", addr_str);
how do I get the resolved (A, AAAA) IP address for the query's hostname? I would like to iterate over A/AAAA IP addresses and CNAMEs in the answer and look at the IP addresses they were resolved to.
Modifying the answer
If the module setting demands it, I would like to be able to "ditch" the resolved answer and provide a new one comprising an A record pointed at a sinkhole.
How do I prepare the record so as it could be translated from char* to Knot's wire format and the proper structure in the right context at the right phase?
I guess it might go along functions such as knot_rrset_init and knot_rrset_add_rdata, but I wasn't able to arrive at any successful result.
THX for pointers and suggestions.
If you want to step in the last moment when the response is finalised but not yet sent to the requestor, the right place is finish. You can do it in consume as well, but you'll be overwriting responses from authoritative servers here, not the assembled response to requestor (which means DNSSEC validator is likely to stop your rewritten answers).
Disclaimer: Go interface is rough and requires a lot of CGO code to access internal structures. You'd be probably better suited by a LuaJIT module, there is another module doing something similar that you may take as an example, it also has wrappers for creating records from text etc. If you still want to do it, that's awesome and improvements to Go interface are welcome, read on.
What you need to do is roughly this (as CGO).
That will walk you through RR sets in the packet (C.knot_rrset_t),
where you can match type (rr.type) and contents (rr.rdata).
Contents is stored in DNS wire format, for address records it is the address in network byte order, e.g. {0x7f, 0, 0, 1}.
You will have to compare that to address/subnet you're looking for - example in C code.
When you find a match, you want to clear the whole packet and insert sinkhole record (you cannot selectively remove records, because the packet is append-only for performance reasons). This is relatively easy as there is a helper for that. Here's code in LuaJIT from policy module, you'd have to rewrite it in Go, using all functions mentioned above and using A/AAAA sinkhole record instead of SOA. Good luck!

Resources