Code By
Lucas Mouilleron

41 projects - An Open Source selection

+ Survival

Shell 63.9% - Lua 35% - Vim script 1.1%
Last update : 28/01/2020 - 20:11

Screenshot

Nice minimal setup for hostile environments :)

Install - Debian / Ubuntu

  • From root or sudo user:usermod -aG sudo username
  • From user username: sudo ls
  • From user username: export SSH_PASSPHRASE="12345" if SSH passphrase desired (more than 5 characters)
  • From user username: cd $HOME;sh <(wget -o /dev/null -qO- https://raw.githubusercontent.com/lucasmouilleron/Survival/master/debian.sh)

Install - macOS

  • From root or sudo user:usermod -aG sudo username
  • From user username: sudo ls
  • From user username: export SSH_PASSPHRASE="12345" if SSH passphrase desired (more than 5 characters)
  • From user username: cd $HOME;sh <(wget -o /dev/null -qO- https://raw.githubusercontent.com/lucasmouilleron/Survival/master/macOS.sh)

Install - Others

TODO :)

+ nicolasrainaud

PHP 79.7% - CSS 8.4% - HTML 7.5% - JavaScript 4.4%
Last update : 28/11/2019 - 10:34

Nicolas Rainaud website, built with my stupidCMS.

Screenshot

+ simpleWebFolder2

Python 57.8% - Mako 37.3% - CSS 4.4% - JavaScript 0.5%
Last update : 18/11/2019 - 13:34

Screenshot

Features

  • List files and folders
  • Nice layout
  • Password protection:
    • drop a .password file containing the desired password in folders (and subfolders) you want to protect
    • drop a .nopassword file in folders (and subfolders) you want to deprotect (in case of protected parent)
  • Listing protection: drop a .nolist file in folders you want to forbid the listing of
  • Show protection: drop a .noshow file in folders you don't want to appear in their parents
  • Download folder as a zip
  • README.md files in folders are interpreted and displayed on top
  • Shares: expiration, path obfuscation, tracking
  • Tracking: optional tracking

Install

  • Pytohn 3
  • pip install -r _sf/requirements.txt
  • Copy _sf/assets/style.sample.css to _sf/assets/style.css
  • Copy _sf/config/config.sample.json to _sf/config/config.json
  • Drop _sf folder in the root folder you want to expose

Customisation

  • Edit _sf/config.json
  • Edit _sf/assets/style.css

TODO

  • Clean shares
  • Better locks
  • Clean locks
  • Track and clean tracking periodicly to file (and not on the fly)

+ watchTower

Python 58.9% - JavaScript 15% - Java 12.8% - HTML 5.4% - CSS 4.1% - Dockerfile 3% - Shell 0.8%
Last update : 02/05/2019 - 08:08

Screenshot

A simple watchtower service.
Heartbeat monitoring + event agregator.

Hearbeat definitions

  • The server is in charge of monitoring services
  • When a service is considered dead, the server then alerts its owner
  • A service is a pulsing agent
  • A pulse is a sign of aliveness
  • When a service pulse the server, it tells him when he will pulse again in the worst case
  • If the service has not pulsed again in time, the server considers the service dead and alerts its owner
  • When a service is no longer required, it must inform the server to avoid a false dead alerts
  • An alert can be a mail, a pushover message, etc.

Event definitions

  • The server is in charge or recieving events
  • When a service sends an event, the server stores it
  • On demand, events can be retrieved for consultation
  • An event is: service + message + level + date of registration

Implementation

  • HTTP client / server architecture
  • All queries protected by password set in HTTP headers under "password"
  • Heartbeat protocol:
    • Pulse:
      • POST /
      • {"service":"SERVICE_NAME","alertType":"ALERT_TYPE","alertTarget":"TARGET_NAME","nextIn":EXPECTED_NEXT_HEARTBEAT_IN_SECS}
    • Cancel:
      • DELETE /
      • {"service":"SERVICE_NAME"}
    • List:
      • GET /
  • Event protocol:
    • Add:
      • POST /add-event
      • {"service":"SERVICE_NAME", "level":"level", "message":"the message"}
    • List:
      • GET /list-events
      • optional params: service (is), from (above), to (below), level (above), message (contains)

Server

  • ./server
  • python3
  • Dependencies: pip install -r requirements.txt
  • Config:
    • config/config.json: main config (cp config/sample.json config/config.json)
    • config/server.crt, config/server.key: SSL certificate, used only if SSL activated
  • Datas: data
  • Deploy:
    • Install dependencies
    • Setup config
    • Generate ssl certificates (optional)
    • Hook in with upstart (optional, ./server/config/sample.upstart.conf, http://upstart.ubuntu.com/getting-started.html)
  • Run: python server.py
  • Docker:
    • ./docker
    • Config: place server config files in ./docker/config
    • Interactive: cd docker && tools/dockerBuild && tools/dockerRun
    • Detached: cd docker && tools/dockerBuild && tools/dockerRunDetached

Server GUI

  • https://hostname.com:443/gui

Java Client

  • ./clientJava
  • Java 7+
  • No dependencies
  • Run test:

Python Client

  • ./clientPython
  • python3
  • Dependencies: requests (pip install requests)
  • Run test: python test.py

Javascript client

  • ./clientJavascript
  • client.js is a node module
  • Dependencies: packages.json -> devDependencies (npm install)
  • Run test: node test.js
  • Run test in browser: browserify test.js -o bundle.js and open test.html in browser

Certificates

  • Self signed: openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt
  • Letsencrypt: TODO

TODO

  • Put data writing in a queue
  • Put alert sending in a queue
  • (Way) better events persister

+ sshForFriends

Shell 100%
Last update : 14/12/2018 - 12:55

Temporally give ssh access to your friends.

sshForFriends uses friends public keys to give them access to the computer.
When sshForFriends has finished running, public keys are cleaned and friends can't access the computer anymore.
Public keys are fetched from known identity providers.

Tested on macOS and Ubuntu.

No password, no hastle, 100% SSH.

Screenshot

Usage

  • sshForFriends [OPTIONS] friendUsername
  • friendUsername is the friend username which will be granted access (identity provider username)
  • sshForFriends -h for more usage help

Identity providers

  • id_rsa: key from cat $HOME/.ssh/id_rsa.pub on your friend's machine (-r RSA_PUB_KEY)
  • Github : keys from https://github.com/$USER_NAME.keys (-g, -i github)
  • Keybase : keys from https://$USER_NAME.keybase.pub/id_rsa.pub (-k, -i keybase)

Behind a firewall

  • If the computer being accessed is behind a firewall, sshForFriends can use a public server for ssh forwading.
  • See params -x, -l, -m and -n
  • On the public server, make sure GatewayPorts yes is set in the /etc/ssh/sshd_config file
  • See examples below

Miscs

  • macOS, enable ssh server : sudo systemsetup -setremotelogin on

Examples

  • Give access from a machine to lucasmouilleron in one line : curl -sL https://raw.githubusercontent.com/lucasmouilleron/sshForFriends/master/sshForFriends -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -g lucasmouilleron
  • Give access from a machine to lucasmouilleron in one line : curl -sL https://raw.githubusercontent.com/lucasmouilleron/sshForFriends/master/sshForFriends -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -k lucasmouilleron
  • Give access from a machine behind a firewall to lucasmouilleron in one line : curl -sL https://raw.githubusercontent.com/lucasmouilleron/sshForFriends/master/sshForFriends -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -g -x lucasmouilleron.com -l sshtunnel -m 10022 lucasmouilleron
  • Give access from a machine behind a firewall to a friend with pub key in one line : curl -sL https://raw.githubusercontent.com/lucasmouilleron/sshForFriends/master/sshForFriends -o $HOME/sshForFriends ; chmod a+x $HOME/sshForFriends ; $HOME/sshForFriends -r "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDqN4/IlNfY8I5AUYYnj9mieJ9Uyx4rMbZjxyukmwM1nqSpTmFBs5xdqtE1Qi1DDb6V0Nphua80GUxXfIiKmbJVuOnrBjX2qInwMPtFxJ0gr8adXYIamcCVylcCPm2qO418KQpuHNM1es5s0a2hzuuRCtw6trysq/SCSIp6o05OEdHP8CbfCdFA+P7sy99XHG3yGzqHdU0D04ScDePzm1buSOXqQRCrSkuLmRMBhtRQSj7UAI3IlRcF3tEFPqAywjwnZVIvv6fUoXnpJuoCzBPuJv5D5lo06xixwIvHc39t1r4Tv/OrD+EyWfPsmCpLGfEkMRBqmj/ds5c4y6NjO9cl" -x lucasmouilleron.com -l sshtunnel -m 10022 yourfriendname

Credits

  • Inspired by https://github.com/flplv/ssh-allow-friend

+ simpleWebFolder

PHP 92.4% - CSS 7.6%
Last update : 04/12/2018 - 09:04

A simple web folder.
For Apache web servers.

Screenshot

Features

  • List files and folders
  • Nice layout
  • Password protection:
    • drop a .password file containing the deisred password in folders (and subfolders) you want to protect
    • drop a .nopassword file in folders (and subfolders) you want to deprotect (in case of protected parent)
  • Download folder as a zip
  • Shares: expiration, path obfuscation, tracking
  • README.md files in folders are interpreted and displayed on top

Install

  • Requires PHP 5+, Apache 2.4+
  • cd _sf;composer install
  • Drop the _sf folder in the root folder
  • Drop the _sf_assets folder in the root folder
  • Create the _sf_shares folders for shares to be activated
  • Drop the .htaccess file in the root folder

Customisation

  • Don't edit files in /_sf
  • Create /_sf_overrides folder
    • Create config.php and override configs defined in _sf/config.php
    • Create style.css and override styles

TODO

  • Clean shares
  • Python ?

+ stupidCMS

PHP 69.5% - JavaScript 19.5% - CSS 6.3% - HTML 4.7%
Last update : 05/05/2018 - 11:12

stupidCMS is a flat file stupid CMS with nice templating and caching engines.

Screenshot

Install

  • Drop all files (including .htaccess) at the site root
  • Create the file ./config.php and override default config (cf Overridable Configuration)

Stupid Pages (SP)

  • Stupid Pages files extensions is .html
  • In Stupid Pages, paths are relative to the site root
  • To link from a page to another page, use http://site.com/other-page
  • They use the Stupid Micro Templating Engine (SMTE) allowing administrable content declaration

Stupid Micro Templating Engine (SMTE)

  • Administrable contents : {{CNT:content-name}}
  • Administrable files : <img src="{{FILE:file-name.jpg}}"/> or <a href="{{FILE:file-name.pdf}}">the file</a>
  • Include another page in a page : {{INC:page-name-without-html-extension}}
  • Definitions : {{DEF:CONSTANT_NAME}} (for example SITE_URL)
  • If : {{IF:php expression}}content{{EIF}}

Studid Dynamic Page (SDP)

  • Stupid Pages files extensions can be .php
  • In this case the page is a Stupid Dynamic Page (SDP)
  • Custom php scripting can be addded
  • <?php global $stupid;?> must be called to make the stupid engine available
  • Sutpid API available :
    • $stupid->__inc("page-name-without-html-extension")
    • $stupid->__cnt("content-name")
    • $stupid->__file("file-name")
  • No CSPC cache is applied (it is applied only for included contents)

Compiled Stupid Pages Caching (CSPC)

  • Compiled Stupid Pages are cached for performance optimization
  • The cache engine is selectable in /config.php
  • Three engines are available :
    • None cache engine : no cache, all pages and contents are loaded from original files (not recommended)
    • File cache engine : cache files are located in /__cache
    • Redis cache engine : redis port is configurable in ___stupid/libs/stupidDefinitions.php
  • In DEVELOPMENT_MODE, the cache is disabled

Stupid Backend (SB)

  • stupidCMS comes with a stupid backend
  • Open http://site.com/admin in browser
  • Content editing :
    • Add contents in pages using the SMTE format
    • Run a Scan to populate the backend interface
    • Edit and save contents
    • Tips :
      • Contents are SMTE compatible, which means you can use the SMTE tags
      • Contents can be written in Markdown format :
  • Files editing :
    • Add files in pages using the SMTE format
    • Run a Scan to populate the backend interface
    • Edit and save files
  • Pages editing :
    • All SP and SDP can be edited from the backend
    • Templates can be used for scaffholding (templates are defined in /__templates)
    • /config.php is editable as well
  • Scan :
    • If SMTE administrable content are not visible, run Scan
    • Scan contents scans for contents and files
  • Clear :
    • If new contents or files don't appear, run Clear, to clear the cache
    • In DEVELOPMENT_MODE, cache is disabled, therefore Clear is not needed
  • Clean : TODO

Administration - Overview

  • Pages are created from backend or manually in root folder (html or php)
  • Reference administrable contents of files with {{CNT:the-content-name}} or {{FILE:the-file-name.pdf}}
  • Scan contents in pages, then edit the contents in the backend
  • Contents : edit contents
  • Files : edit files
  • Scan : scan for new contents or files referenced in pages
  • Pages : add or edit pages

Administration - Contents

  • Scan : scan for new files referenced in pages
  • Go to Contents
  • Edit the relevant content
  • Edit one content at the time (the Save button (or ctrl+shift+enter) save only the current content)
  • To use Markdown syntax, the first line of content must be ***

Administration - Files

  • Scan : scan for new files referenced in pages
  • Go to Files
  • Upload the relevant file with the Replace button

Overridable configuration

  • Defined in ___stupid/libs/stupidDefinitions.php
  • DEBUG_MODE (true): displays hints
  • DEVELOPMENT_MODE (false): no cache for easier development
  • ADMIN_PASSWORD ("password"): has to be changed
  • SITE_URL ("http://localhost"): has to be set to the site root url
  • PAGE_404 (false): false or the name of the 404 page (without extension)
  • NO_SCAN_FOLDERS (none): folders not to scan when finding contents and files
  • SMTE_CACHE_ENGINE ("file"): file | redis | none

Dev

  • Install composer : curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer
  • Install dependencies : cd ___stupid && composer install
  • Underlying cotents in ./__contents
  • Underlying files in ./__files

TODO

  • sub folder index
  • guidlines

Naming

Menus

+ lucasmouilleron

PHP 67.2% - JavaScript 18.6% - CSS 11.4% - HTML 2.7%
Last update : 25/04/2018 - 20:26

My personal website.

Screenshot

+ riverworldBeings

Python 98.1% - CSS 1.9%
Last update : 17/01/2018 - 14:32

Characterisation of the population of beings of Riverworld.

Riverworld is a fictional planet and the setting for a series of sci-fi books written by Philip José Farmer.
Riverworld is an artificial environment where all humans (and pre-humans) ever born who died after reaching 5 years old are reconstructed.
Most of the resurrected awaken in a body equivalent to that of their 25 year old selves, in perfect health and free of any previous genetic or acquired defects.

A friend of mine made fun of the book concept and claimed half of the beings ressucitated would be prehistorical.

This project is proving him wrong.

Definitions

  • Begining of mankind : Homo Erectus, -1500K, assuming all beings on Riverworld can walk
  • End of mankind : 2016. In the book, all people die in 1983 after interacting with an alien civilisation.
  • Child Mortality CM : death of infants and children under the age of 5
  • Infant Mortality IM : death of infants and children under the age of 1
  • Life Expectancy LE : average time a being is expected to live
  • Life Adult Expectancy LAE : average time a being is expected to live if he reachs 5 years old

Datas

  • Dataset compiled amongst considered sources :
    • until now, conservative estimations for pre modern times : ./data/population-min.csv
    • until now, optimistic estimations for pre modern times : ./data/population-max.csv
    • until now, average estimations for pre modern times : ./data/population-avg.csv
    • including 2070 projections ./data/population-future.csv
  • The dataset consists of Point In Times (PIT)
  • For each PIT, these metrics are available : year, beings count in millions, LE, LAE, CM and continental proportions
  • Depending on sources, CM, IM, LE and/or LAE are provided or not. Some datas have been extrapolated. Underlying model : LE = CM * 5/2 + LAE * (1 - CM)
  • Case of beings count in prehistorical times :
    • Beings counts estimation flucuates a lot. They can go as low as 1K individuals up to 100K
    • We have 3 milestones in our dataset : -1500K (lower paleolithic), -50K (higher paleolithic) and -10K (begining of history)
    • For -10K, the poulation count is within the magnitude of the millions according to most of the sources. We kept the McEvedy estimation of 4 millions.
    • For -50K, we kept the higher estimation of Jean-Pierre Bocquet-Appel from his study of upper paleolithical meta populations in Europe. He found 15K individuals in the Aurignacien (-30K). Wordlwide, we estimated, as a minimum, we timed this result by 5. As a maximum by 10.
    • For -1500K, we've assumed the population could not be higher than in -50K. We assumed the population at that time would be the population of -50K / 2.
  • Case of LE et CM for prehistorical times :
    • As for beings counts, the LE estimations vary greatly
    • The Kaplan study suggest hunter gatherer modern societies tell us how prehistoric men lived and died. The study suggests the ALE is around 50 years and the CM around 0.5
    • For reference, the CM of 1900 is 0.4 and the Scheidel estimation of Classic Rome CM is 0.5
    • We cowardly derived the CM of pre Roman times to 0.6

Calculus

  • Linearity in between PITs :
    • The underlying assumption is that the PIT metrics evolve linearly in between two PITs
    • This assumption can be considered true from -1500K to 1700, from 1700 to 1900, from 1900 to 1950 and from 1950 to today
    • The PIT resolution in the dataset is consistent with this observation
    • We then assume numerical midpoint integration is a reasonable estimation
  • For the period PIT 1 => PIT 2
  • AB yx = Amount of Beings for year x
  • Elapsed Time ET = y2 - y1
  • Average Amount of Beings for Period AABP = (AB y2 + AB y1) / 2
  • LAE for Period LAEP = (LAE y1 + LAE y2) / 2
  • Proportion of Adult Beings To Be for Period PABTBP = 1 - ((CM y1 + CM y2) / 2)
  • Thus Amount of Beings who were Born for Period ABP = ET * AABP / LAEP
  • Thus Amount of Adult Beings who were Born for Period AABP = ET * AABP * PABTBP / LEP
  • Another calculus method is to use a simpe model of population growth :
    • AB y1 = Ce^(r * y1) and AB y2 = Ce^(r * y2)
    • By integration, ABP = ET * (AB y2 - AB y1) / (ln(AB y2) - ln(AB y1)) / LEP
    • This method proved to be very similar to the naïve numerical integration we selected (cf Report - Figure 6)

Results

  • The last report : ./output/(min|max|future)/report.pdf
  • The last plots : ./output

Sources

Install

  • pip install --upgrade pip
  • pip install -r requirements.txt --user
  • Fonts used in this project : ./resources/fonts
  • PDF dependencies :
    • mac : brew cask install wkhtmltopdf
    • linux : apt-get install wkhtmltopdf

Run

  • Configuration is loaded from config.ini
  • python riverworld.py min|max|avg|future
  • all at once : python riverworld.py min;python riverworld.py max;python riverworld.py avg;python riverworld.py future

Credits

+ TCTBlog

Last update : 17/01/2018 - 14:28
  • Everything is in gh-pages branch
  • Needed for github pages publication
  • To edit the blog, switch to gh-pages branch